Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v5.3-rc6 421 lines 12 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Faraday Technology FTTMR010 timer driver 4 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> 5 * 6 * Based on a rewrite of arch/arm/mach-gemini/timer.c: 7 * Copyright (C) 2001-2006 Storlink, Corp. 8 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 9 */ 10#include <linux/interrupt.h> 11#include <linux/io.h> 12#include <linux/of.h> 13#include <linux/of_address.h> 14#include <linux/of_irq.h> 15#include <linux/clockchips.h> 16#include <linux/clocksource.h> 17#include <linux/sched_clock.h> 18#include <linux/clk.h> 19#include <linux/slab.h> 20#include <linux/bitops.h> 21#include <linux/delay.h> 22 23/* 24 * Register definitions common for all the timer variants. 25 */ 26#define TIMER1_COUNT (0x00) 27#define TIMER1_LOAD (0x04) 28#define TIMER1_MATCH1 (0x08) 29#define TIMER1_MATCH2 (0x0c) 30#define TIMER2_COUNT (0x10) 31#define TIMER2_LOAD (0x14) 32#define TIMER2_MATCH1 (0x18) 33#define TIMER2_MATCH2 (0x1c) 34#define TIMER3_COUNT (0x20) 35#define TIMER3_LOAD (0x24) 36#define TIMER3_MATCH1 (0x28) 37#define TIMER3_MATCH2 (0x2c) 38#define TIMER_CR (0x30) 39 40/* 41 * Control register (TMC30) bit fields for fttmr010/gemini/moxart timers. 42 */ 43#define TIMER_1_CR_ENABLE BIT(0) 44#define TIMER_1_CR_CLOCK BIT(1) 45#define TIMER_1_CR_INT BIT(2) 46#define TIMER_2_CR_ENABLE BIT(3) 47#define TIMER_2_CR_CLOCK BIT(4) 48#define TIMER_2_CR_INT BIT(5) 49#define TIMER_3_CR_ENABLE BIT(6) 50#define TIMER_3_CR_CLOCK BIT(7) 51#define TIMER_3_CR_INT BIT(8) 52#define TIMER_1_CR_UPDOWN BIT(9) 53#define TIMER_2_CR_UPDOWN BIT(10) 54#define TIMER_3_CR_UPDOWN BIT(11) 55 56/* 57 * Control register (TMC30) bit fields for aspeed ast2400/ast2500 timers. 58 * The aspeed timers move bits around in the control register and lacks 59 * bits for setting the timer to count upwards. 60 */ 61#define TIMER_1_CR_ASPEED_ENABLE BIT(0) 62#define TIMER_1_CR_ASPEED_CLOCK BIT(1) 63#define TIMER_1_CR_ASPEED_INT BIT(2) 64#define TIMER_2_CR_ASPEED_ENABLE BIT(4) 65#define TIMER_2_CR_ASPEED_CLOCK BIT(5) 66#define TIMER_2_CR_ASPEED_INT BIT(6) 67#define TIMER_3_CR_ASPEED_ENABLE BIT(8) 68#define TIMER_3_CR_ASPEED_CLOCK BIT(9) 69#define TIMER_3_CR_ASPEED_INT BIT(10) 70 71/* 72 * Interrupt status/mask register definitions for fttmr010/gemini/moxart 73 * timers. 74 * The registers don't exist and they are not needed on aspeed timers 75 * because: 76 * - aspeed timer overflow interrupt is controlled by bits in Control 77 * Register (TMC30). 78 * - aspeed timers always generate interrupt when either one of the 79 * Match registers equals to Status register. 80 */ 81#define TIMER_INTR_STATE (0x34) 82#define TIMER_INTR_MASK (0x38) 83#define TIMER_1_INT_MATCH1 BIT(0) 84#define TIMER_1_INT_MATCH2 BIT(1) 85#define TIMER_1_INT_OVERFLOW BIT(2) 86#define TIMER_2_INT_MATCH1 BIT(3) 87#define TIMER_2_INT_MATCH2 BIT(4) 88#define TIMER_2_INT_OVERFLOW BIT(5) 89#define TIMER_3_INT_MATCH1 BIT(6) 90#define TIMER_3_INT_MATCH2 BIT(7) 91#define TIMER_3_INT_OVERFLOW BIT(8) 92#define TIMER_INT_ALL_MASK 0x1ff 93 94struct fttmr010 { 95 void __iomem *base; 96 unsigned int tick_rate; 97 bool is_aspeed; 98 u32 t1_enable_val; 99 struct clock_event_device clkevt; 100#ifdef CONFIG_ARM 101 struct delay_timer delay_timer; 102#endif 103}; 104 105/* 106 * A local singleton used by sched_clock and delay timer reads, which are 107 * fast and stateless 108 */ 109static struct fttmr010 *local_fttmr; 110 111static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt) 112{ 113 return container_of(evt, struct fttmr010, clkevt); 114} 115 116static unsigned long fttmr010_read_current_timer_up(void) 117{ 118 return readl(local_fttmr->base + TIMER2_COUNT); 119} 120 121static unsigned long fttmr010_read_current_timer_down(void) 122{ 123 return ~readl(local_fttmr->base + TIMER2_COUNT); 124} 125 126static u64 notrace fttmr010_read_sched_clock_up(void) 127{ 128 return fttmr010_read_current_timer_up(); 129} 130 131static u64 notrace fttmr010_read_sched_clock_down(void) 132{ 133 return fttmr010_read_current_timer_down(); 134} 135 136static int fttmr010_timer_set_next_event(unsigned long cycles, 137 struct clock_event_device *evt) 138{ 139 struct fttmr010 *fttmr010 = to_fttmr010(evt); 140 u32 cr; 141 142 /* Stop */ 143 cr = readl(fttmr010->base + TIMER_CR); 144 cr &= ~fttmr010->t1_enable_val; 145 writel(cr, fttmr010->base + TIMER_CR); 146 147 if (fttmr010->is_aspeed) { 148 /* 149 * ASPEED Timer Controller will load TIMER1_LOAD register 150 * into TIMER1_COUNT register when the timer is re-enabled. 151 */ 152 writel(cycles, fttmr010->base + TIMER1_LOAD); 153 } else { 154 /* Setup the match register forward in time */ 155 cr = readl(fttmr010->base + TIMER1_COUNT); 156 writel(cr + cycles, fttmr010->base + TIMER1_MATCH1); 157 } 158 159 /* Start */ 160 cr = readl(fttmr010->base + TIMER_CR); 161 cr |= fttmr010->t1_enable_val; 162 writel(cr, fttmr010->base + TIMER_CR); 163 164 return 0; 165} 166 167static int fttmr010_timer_shutdown(struct clock_event_device *evt) 168{ 169 struct fttmr010 *fttmr010 = to_fttmr010(evt); 170 u32 cr; 171 172 /* Stop */ 173 cr = readl(fttmr010->base + TIMER_CR); 174 cr &= ~fttmr010->t1_enable_val; 175 writel(cr, fttmr010->base + TIMER_CR); 176 177 return 0; 178} 179 180static int fttmr010_timer_set_oneshot(struct clock_event_device *evt) 181{ 182 struct fttmr010 *fttmr010 = to_fttmr010(evt); 183 u32 cr; 184 185 /* Stop */ 186 cr = readl(fttmr010->base + TIMER_CR); 187 cr &= ~fttmr010->t1_enable_val; 188 writel(cr, fttmr010->base + TIMER_CR); 189 190 /* Setup counter start from 0 or ~0 */ 191 writel(0, fttmr010->base + TIMER1_COUNT); 192 if (fttmr010->is_aspeed) { 193 writel(~0, fttmr010->base + TIMER1_LOAD); 194 } else { 195 writel(0, fttmr010->base + TIMER1_LOAD); 196 197 /* Enable interrupt */ 198 cr = readl(fttmr010->base + TIMER_INTR_MASK); 199 cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2); 200 cr |= TIMER_1_INT_MATCH1; 201 writel(cr, fttmr010->base + TIMER_INTR_MASK); 202 } 203 204 return 0; 205} 206 207static int fttmr010_timer_set_periodic(struct clock_event_device *evt) 208{ 209 struct fttmr010 *fttmr010 = to_fttmr010(evt); 210 u32 period = DIV_ROUND_CLOSEST(fttmr010->tick_rate, HZ); 211 u32 cr; 212 213 /* Stop */ 214 cr = readl(fttmr010->base + TIMER_CR); 215 cr &= ~fttmr010->t1_enable_val; 216 writel(cr, fttmr010->base + TIMER_CR); 217 218 /* Setup timer to fire at 1/HZ intervals. */ 219 if (fttmr010->is_aspeed) { 220 writel(period, fttmr010->base + TIMER1_LOAD); 221 } else { 222 cr = 0xffffffff - (period - 1); 223 writel(cr, fttmr010->base + TIMER1_COUNT); 224 writel(cr, fttmr010->base + TIMER1_LOAD); 225 226 /* Enable interrupt on overflow */ 227 cr = readl(fttmr010->base + TIMER_INTR_MASK); 228 cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2); 229 cr |= TIMER_1_INT_OVERFLOW; 230 writel(cr, fttmr010->base + TIMER_INTR_MASK); 231 } 232 233 /* Start the timer */ 234 cr = readl(fttmr010->base + TIMER_CR); 235 cr |= fttmr010->t1_enable_val; 236 writel(cr, fttmr010->base + TIMER_CR); 237 238 return 0; 239} 240 241/* 242 * IRQ handler for the timer 243 */ 244static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id) 245{ 246 struct clock_event_device *evt = dev_id; 247 248 evt->event_handler(evt); 249 return IRQ_HANDLED; 250} 251 252static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) 253{ 254 struct fttmr010 *fttmr010; 255 int irq; 256 struct clk *clk; 257 int ret; 258 u32 val; 259 260 /* 261 * These implementations require a clock reference. 262 * FIXME: we currently only support clocking using PCLK 263 * and using EXTCLK is not supported in the driver. 264 */ 265 clk = of_clk_get_by_name(np, "PCLK"); 266 if (IS_ERR(clk)) { 267 pr_err("could not get PCLK\n"); 268 return PTR_ERR(clk); 269 } 270 ret = clk_prepare_enable(clk); 271 if (ret) { 272 pr_err("failed to enable PCLK\n"); 273 return ret; 274 } 275 276 fttmr010 = kzalloc(sizeof(*fttmr010), GFP_KERNEL); 277 if (!fttmr010) { 278 ret = -ENOMEM; 279 goto out_disable_clock; 280 } 281 fttmr010->tick_rate = clk_get_rate(clk); 282 283 fttmr010->base = of_iomap(np, 0); 284 if (!fttmr010->base) { 285 pr_err("Can't remap registers\n"); 286 ret = -ENXIO; 287 goto out_free; 288 } 289 /* IRQ for timer 1 */ 290 irq = irq_of_parse_and_map(np, 0); 291 if (irq <= 0) { 292 pr_err("Can't parse IRQ\n"); 293 ret = -EINVAL; 294 goto out_unmap; 295 } 296 297 /* 298 * The Aspeed timers move bits around in the control register. 299 */ 300 if (is_aspeed) { 301 fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE | 302 TIMER_1_CR_ASPEED_INT; 303 fttmr010->is_aspeed = true; 304 } else { 305 fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT; 306 307 /* 308 * Reset the interrupt mask and status 309 */ 310 writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK); 311 writel(0, fttmr010->base + TIMER_INTR_STATE); 312 } 313 314 /* 315 * Enable timer 1 count up, timer 2 count up, except on Aspeed, 316 * where everything just counts down. 317 */ 318 if (is_aspeed) 319 val = TIMER_2_CR_ASPEED_ENABLE; 320 else { 321 val = TIMER_2_CR_ENABLE | TIMER_1_CR_UPDOWN | 322 TIMER_2_CR_UPDOWN; 323 } 324 writel(val, fttmr010->base + TIMER_CR); 325 326 /* 327 * Setup free-running clocksource timer (interrupts 328 * disabled.) 329 */ 330 local_fttmr = fttmr010; 331 writel(0, fttmr010->base + TIMER2_COUNT); 332 writel(0, fttmr010->base + TIMER2_MATCH1); 333 writel(0, fttmr010->base + TIMER2_MATCH2); 334 335 if (fttmr010->is_aspeed) { 336 writel(~0, fttmr010->base + TIMER2_LOAD); 337 clocksource_mmio_init(fttmr010->base + TIMER2_COUNT, 338 "FTTMR010-TIMER2", 339 fttmr010->tick_rate, 340 300, 32, clocksource_mmio_readl_down); 341 sched_clock_register(fttmr010_read_sched_clock_down, 32, 342 fttmr010->tick_rate); 343 } else { 344 writel(0, fttmr010->base + TIMER2_LOAD); 345 clocksource_mmio_init(fttmr010->base + TIMER2_COUNT, 346 "FTTMR010-TIMER2", 347 fttmr010->tick_rate, 348 300, 32, clocksource_mmio_readl_up); 349 sched_clock_register(fttmr010_read_sched_clock_up, 32, 350 fttmr010->tick_rate); 351 } 352 353 /* 354 * Setup clockevent timer (interrupt-driven) on timer 1. 355 */ 356 writel(0, fttmr010->base + TIMER1_COUNT); 357 writel(0, fttmr010->base + TIMER1_LOAD); 358 writel(0, fttmr010->base + TIMER1_MATCH1); 359 writel(0, fttmr010->base + TIMER1_MATCH2); 360 ret = request_irq(irq, fttmr010_timer_interrupt, IRQF_TIMER, 361 "FTTMR010-TIMER1", &fttmr010->clkevt); 362 if (ret) { 363 pr_err("FTTMR010-TIMER1 no IRQ\n"); 364 goto out_unmap; 365 } 366 367 fttmr010->clkevt.name = "FTTMR010-TIMER1"; 368 /* Reasonably fast and accurate clock event */ 369 fttmr010->clkevt.rating = 300; 370 fttmr010->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | 371 CLOCK_EVT_FEAT_ONESHOT; 372 fttmr010->clkevt.set_next_event = fttmr010_timer_set_next_event; 373 fttmr010->clkevt.set_state_shutdown = fttmr010_timer_shutdown; 374 fttmr010->clkevt.set_state_periodic = fttmr010_timer_set_periodic; 375 fttmr010->clkevt.set_state_oneshot = fttmr010_timer_set_oneshot; 376 fttmr010->clkevt.tick_resume = fttmr010_timer_shutdown; 377 fttmr010->clkevt.cpumask = cpumask_of(0); 378 fttmr010->clkevt.irq = irq; 379 clockevents_config_and_register(&fttmr010->clkevt, 380 fttmr010->tick_rate, 381 1, 0xffffffff); 382 383#ifdef CONFIG_ARM 384 /* Also use this timer for delays */ 385 if (fttmr010->is_aspeed) 386 fttmr010->delay_timer.read_current_timer = 387 fttmr010_read_current_timer_down; 388 else 389 fttmr010->delay_timer.read_current_timer = 390 fttmr010_read_current_timer_up; 391 fttmr010->delay_timer.freq = fttmr010->tick_rate; 392 register_current_timer_delay(&fttmr010->delay_timer); 393#endif 394 395 return 0; 396 397out_unmap: 398 iounmap(fttmr010->base); 399out_free: 400 kfree(fttmr010); 401out_disable_clock: 402 clk_disable_unprepare(clk); 403 404 return ret; 405} 406 407static __init int aspeed_timer_init(struct device_node *np) 408{ 409 return fttmr010_common_init(np, true); 410} 411 412static __init int fttmr010_timer_init(struct device_node *np) 413{ 414 return fttmr010_common_init(np, false); 415} 416 417TIMER_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init); 418TIMER_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init); 419TIMER_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init); 420TIMER_OF_DECLARE(ast2400, "aspeed,ast2400-timer", aspeed_timer_init); 421TIMER_OF_DECLARE(ast2500, "aspeed,ast2500-timer", aspeed_timer_init);