1 /* 2 * Faraday Technology FTTMR010 timer driver 3 * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> 4 * 5 * Based on a rewrite of arch/arm/mach-gemini/timer.c: 6 * Copyright (C) 2001-2006 Storlink, Corp. 7 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 8 */ 9 #include <linux/interrupt.h> 10 #include <linux/io.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/of_irq.h> 14 #include <linux/mfd/syscon.h> 15 #include <linux/regmap.h> 16 #include <linux/clockchips.h> 17 #include <linux/clocksource.h> 18 #include <linux/sched_clock.h> 19 #include <linux/clk.h> 20 21 /* 22 * Register definitions for the timers 23 */ 24 #define TIMER1_COUNT (0x00) 25 #define TIMER1_LOAD (0x04) 26 #define TIMER1_MATCH1 (0x08) 27 #define TIMER1_MATCH2 (0x0c) 28 #define TIMER2_COUNT (0x10) 29 #define TIMER2_LOAD (0x14) 30 #define TIMER2_MATCH1 (0x18) 31 #define TIMER2_MATCH2 (0x1c) 32 #define TIMER3_COUNT (0x20) 33 #define TIMER3_LOAD (0x24) 34 #define TIMER3_MATCH1 (0x28) 35 #define TIMER3_MATCH2 (0x2c) 36 #define TIMER_CR (0x30) 37 #define TIMER_INTR_STATE (0x34) 38 #define TIMER_INTR_MASK (0x38) 39 40 #define TIMER_1_CR_ENABLE (1 << 0) 41 #define TIMER_1_CR_CLOCK (1 << 1) 42 #define TIMER_1_CR_INT (1 << 2) 43 #define TIMER_2_CR_ENABLE (1 << 3) 44 #define TIMER_2_CR_CLOCK (1 << 4) 45 #define TIMER_2_CR_INT (1 << 5) 46 #define TIMER_3_CR_ENABLE (1 << 6) 47 #define TIMER_3_CR_CLOCK (1 << 7) 48 #define TIMER_3_CR_INT (1 << 8) 49 #define TIMER_1_CR_UPDOWN (1 << 9) 50 #define TIMER_2_CR_UPDOWN (1 << 10) 51 #define TIMER_3_CR_UPDOWN (1 << 11) 52 #define TIMER_DEFAULT_FLAGS (TIMER_1_CR_UPDOWN | \ 53 TIMER_3_CR_ENABLE | \ 54 TIMER_3_CR_UPDOWN) 55 56 #define TIMER_1_INT_MATCH1 (1 << 0) 57 #define TIMER_1_INT_MATCH2 (1 << 1) 58 #define TIMER_1_INT_OVERFLOW (1 << 2) 59 #define TIMER_2_INT_MATCH1 (1 << 3) 60 #define TIMER_2_INT_MATCH2 (1 << 4) 61 #define TIMER_2_INT_OVERFLOW (1 << 5) 62 #define TIMER_3_INT_MATCH1 (1 << 6) 63 #define TIMER_3_INT_MATCH2 (1 << 7) 64 #define TIMER_3_INT_OVERFLOW (1 << 8) 65 #define TIMER_INT_ALL_MASK 0x1ff 66 67 static unsigned int tick_rate; 68 static void __iomem *base; 69 70 static u64 notrace fttmr010_read_sched_clock(void) 71 { 72 return readl(base + TIMER3_COUNT); 73 } 74 75 static int fttmr010_timer_set_next_event(unsigned long cycles, 76 struct clock_event_device *evt) 77 { 78 u32 cr; 79 80 /* Setup the match register */ 81 cr = readl(base + TIMER1_COUNT); 82 writel(cr + cycles, base + TIMER1_MATCH1); 83 if (readl(base + TIMER1_COUNT) - cr > cycles) 84 return -ETIME; 85 86 return 0; 87 } 88 89 static int fttmr010_timer_shutdown(struct clock_event_device *evt) 90 { 91 u32 cr; 92 93 /* 94 * Disable also for oneshot: the set_next() call will arm the timer 95 * instead. 96 */ 97 /* Stop timer and interrupt. */ 98 cr = readl(base + TIMER_CR); 99 cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT); 100 writel(cr, base + TIMER_CR); 101 102 /* Setup counter start from 0 */ 103 writel(0, base + TIMER1_COUNT); 104 writel(0, base + TIMER1_LOAD); 105 106 /* enable interrupt */ 107 cr = readl(base + TIMER_INTR_MASK); 108 cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2); 109 cr |= TIMER_1_INT_MATCH1; 110 writel(cr, base + TIMER_INTR_MASK); 111 112 /* start the timer */ 113 cr = readl(base + TIMER_CR); 114 cr |= TIMER_1_CR_ENABLE; 115 writel(cr, base + TIMER_CR); 116 117 return 0; 118 } 119 120 static int fttmr010_timer_set_periodic(struct clock_event_device *evt) 121 { 122 u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ); 123 u32 cr; 124 125 /* Stop timer and interrupt */ 126 cr = readl(base + TIMER_CR); 127 cr &= ~(TIMER_1_CR_ENABLE | TIMER_1_CR_INT); 128 writel(cr, base + TIMER_CR); 129 130 /* Setup timer to fire at 1/HT intervals. */ 131 cr = 0xffffffff - (period - 1); 132 writel(cr, base + TIMER1_COUNT); 133 writel(cr, base + TIMER1_LOAD); 134 135 /* enable interrupt on overflow */ 136 cr = readl(base + TIMER_INTR_MASK); 137 cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2); 138 cr |= TIMER_1_INT_OVERFLOW; 139 writel(cr, base + TIMER_INTR_MASK); 140 141 /* Start the timer */ 142 cr = readl(base + TIMER_CR); 143 cr |= TIMER_1_CR_ENABLE; 144 cr |= TIMER_1_CR_INT; 145 writel(cr, base + TIMER_CR); 146 147 return 0; 148 } 149 150 /* Use TIMER1 as clock event */ 151 static struct clock_event_device fttmr010_clockevent = { 152 .name = "TIMER1", 153 /* Reasonably fast and accurate clock event */ 154 .rating = 300, 155 .shift = 32, 156 .features = CLOCK_EVT_FEAT_PERIODIC | 157 CLOCK_EVT_FEAT_ONESHOT, 158 .set_next_event = fttmr010_timer_set_next_event, 159 .set_state_shutdown = fttmr010_timer_shutdown, 160 .set_state_periodic = fttmr010_timer_set_periodic, 161 .set_state_oneshot = fttmr010_timer_shutdown, 162 .tick_resume = fttmr010_timer_shutdown, 163 }; 164 165 /* 166 * IRQ handler for the timer 167 */ 168 static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id) 169 { 170 struct clock_event_device *evt = &fttmr010_clockevent; 171 172 evt->event_handler(evt); 173 return IRQ_HANDLED; 174 } 175 176 static struct irqaction fttmr010_timer_irq = { 177 .name = "Faraday FTTMR010 Timer Tick", 178 .flags = IRQF_TIMER, 179 .handler = fttmr010_timer_interrupt, 180 }; 181 182 static int __init fttmr010_timer_common_init(struct device_node *np) 183 { 184 int irq; 185 186 base = of_iomap(np, 0); 187 if (!base) { 188 pr_err("Can't remap registers"); 189 return -ENXIO; 190 } 191 /* IRQ for timer 1 */ 192 irq = irq_of_parse_and_map(np, 0); 193 if (irq <= 0) { 194 pr_err("Can't parse IRQ"); 195 return -EINVAL; 196 } 197 198 /* 199 * Reset the interrupt mask and status 200 */ 201 writel(TIMER_INT_ALL_MASK, base + TIMER_INTR_MASK); 202 writel(0, base + TIMER_INTR_STATE); 203 writel(TIMER_DEFAULT_FLAGS, base + TIMER_CR); 204 205 /* 206 * Setup free-running clocksource timer (interrupts 207 * disabled.) 208 */ 209 writel(0, base + TIMER3_COUNT); 210 writel(0, base + TIMER3_LOAD); 211 writel(0, base + TIMER3_MATCH1); 212 writel(0, base + TIMER3_MATCH2); 213 clocksource_mmio_init(base + TIMER3_COUNT, 214 "fttmr010_clocksource", tick_rate, 215 300, 32, clocksource_mmio_readl_up); 216 sched_clock_register(fttmr010_read_sched_clock, 32, tick_rate); 217 218 /* 219 * Setup clockevent timer (interrupt-driven.) 220 */ 221 writel(0, base + TIMER1_COUNT); 222 writel(0, base + TIMER1_LOAD); 223 writel(0, base + TIMER1_MATCH1); 224 writel(0, base + TIMER1_MATCH2); 225 setup_irq(irq, &fttmr010_timer_irq); 226 fttmr010_clockevent.cpumask = cpumask_of(0); 227 clockevents_config_and_register(&fttmr010_clockevent, tick_rate, 228 1, 0xffffffff); 229 230 return 0; 231 } 232 233 static int __init fttmr010_timer_of_init(struct device_node *np) 234 { 235 /* 236 * These implementations require a clock reference. 237 * FIXME: we currently only support clocking using PCLK 238 * and using EXTCLK is not supported in the driver. 239 */ 240 struct clk *clk; 241 242 clk = of_clk_get_by_name(np, "PCLK"); 243 if (IS_ERR(clk)) { 244 pr_err("could not get PCLK"); 245 return PTR_ERR(clk); 246 } 247 tick_rate = clk_get_rate(clk); 248 249 return fttmr010_timer_common_init(np); 250 } 251 CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_of_init); 252 253 /* 254 * Gemini-specific: relevant registers in the global syscon 255 */ 256 #define GLOBAL_STATUS 0x04 257 #define CPU_AHB_RATIO_MASK (0x3 << 18) 258 #define CPU_AHB_1_1 (0x0 << 18) 259 #define CPU_AHB_3_2 (0x1 << 18) 260 #define CPU_AHB_24_13 (0x2 << 18) 261 #define CPU_AHB_2_1 (0x3 << 18) 262 #define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130) 263 264 static int __init gemini_timer_of_init(struct device_node *np) 265 { 266 static struct regmap *map; 267 int ret; 268 u32 val; 269 270 map = syscon_regmap_lookup_by_phandle(np, "syscon"); 271 if (IS_ERR(map)) { 272 pr_err("Can't get regmap for syscon handle\n"); 273 return -ENODEV; 274 } 275 ret = regmap_read(map, GLOBAL_STATUS, &val); 276 if (ret) { 277 pr_err("Can't read syscon status register\n"); 278 return -ENXIO; 279 } 280 281 tick_rate = REG_TO_AHB_SPEED(val) * 1000000; 282 pr_info("Bus: %dMHz ", tick_rate / 1000000); 283 284 tick_rate /= 6; /* APB bus run AHB*(1/6) */ 285 286 switch (val & CPU_AHB_RATIO_MASK) { 287 case CPU_AHB_1_1: 288 pr_cont("(1/1)\n"); 289 break; 290 case CPU_AHB_3_2: 291 pr_cont("(3/2)\n"); 292 break; 293 case CPU_AHB_24_13: 294 pr_cont("(24/13)\n"); 295 break; 296 case CPU_AHB_2_1: 297 pr_cont("(2/1)\n"); 298 break; 299 } 300 301 return fttmr010_timer_common_init(np); 302 } 303 CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", gemini_timer_of_init); 304