time-armada-370-xp.c revision 573145f08c2b92c45498468afbbba909f6ce6135
1/* 2 * Marvell Armada 370/XP SoC timer handling. 3 * 4 * Copyright (C) 2012 Marvell 5 * 6 * Lior Amsalem <alior@marvell.com> 7 * Gregory CLEMENT <gregory.clement@free-electrons.com> 8 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 9 * 10 * This file is licensed under the terms of the GNU General Public 11 * License version 2. This program is licensed "as is" without any 12 * warranty of any kind, whether express or implied. 13 * 14 * Timer 0 is used as free-running clocksource, while timer 1 is 15 * used as clock_event_device. 16 */ 17 18#include <linux/init.h> 19#include <linux/platform_device.h> 20#include <linux/kernel.h> 21#include <linux/clk.h> 22#include <linux/timer.h> 23#include <linux/clockchips.h> 24#include <linux/interrupt.h> 25#include <linux/of.h> 26#include <linux/of_irq.h> 27#include <linux/of_address.h> 28#include <linux/irq.h> 29#include <linux/module.h> 30#include <linux/sched_clock.h> 31 32#include <asm/localtimer.h> 33#include <linux/percpu.h> 34/* 35 * Timer block registers. 36 */ 37#define TIMER_CTRL_OFF 0x0000 38#define TIMER0_EN BIT(0) 39#define TIMER0_RELOAD_EN BIT(1) 40#define TIMER0_25MHZ BIT(11) 41#define TIMER0_DIV(div) ((div) << 19) 42#define TIMER1_EN BIT(2) 43#define TIMER1_RELOAD_EN BIT(3) 44#define TIMER1_25MHZ BIT(12) 45#define TIMER1_DIV(div) ((div) << 22) 46#define TIMER_EVENTS_STATUS 0x0004 47#define TIMER0_CLR_MASK (~0x1) 48#define TIMER1_CLR_MASK (~0x100) 49#define TIMER0_RELOAD_OFF 0x0010 50#define TIMER0_VAL_OFF 0x0014 51#define TIMER1_RELOAD_OFF 0x0018 52#define TIMER1_VAL_OFF 0x001c 53 54#define LCL_TIMER_EVENTS_STATUS 0x0028 55/* Global timers are connected to the coherency fabric clock, and the 56 below divider reduces their incrementing frequency. */ 57#define TIMER_DIVIDER_SHIFT 5 58#define TIMER_DIVIDER (1 << TIMER_DIVIDER_SHIFT) 59 60/* 61 * SoC-specific data. 62 */ 63static void __iomem *timer_base, *local_base; 64static unsigned int timer_clk; 65static bool timer25Mhz = true; 66 67/* 68 * Number of timer ticks per jiffy. 69 */ 70static u32 ticks_per_jiffy; 71 72static struct clock_event_device __percpu **percpu_armada_370_xp_evt; 73 74static void timer_ctrl_clrset(u32 clr, u32 set) 75{ 76 writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set, 77 timer_base + TIMER_CTRL_OFF); 78} 79 80static void local_timer_ctrl_clrset(u32 clr, u32 set) 81{ 82 writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set, 83 local_base + TIMER_CTRL_OFF); 84} 85 86static u32 notrace armada_370_xp_read_sched_clock(void) 87{ 88 return ~readl(timer_base + TIMER0_VAL_OFF); 89} 90 91/* 92 * Clockevent handling. 93 */ 94static int 95armada_370_xp_clkevt_next_event(unsigned long delta, 96 struct clock_event_device *dev) 97{ 98 /* 99 * Clear clockevent timer interrupt. 100 */ 101 writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); 102 103 /* 104 * Setup new clockevent timer value. 105 */ 106 writel(delta, local_base + TIMER0_VAL_OFF); 107 108 /* 109 * Enable the timer. 110 */ 111 local_timer_ctrl_clrset(TIMER0_RELOAD_EN, 112 TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); 113 return 0; 114} 115 116static void 117armada_370_xp_clkevt_mode(enum clock_event_mode mode, 118 struct clock_event_device *dev) 119{ 120 if (mode == CLOCK_EVT_MODE_PERIODIC) { 121 122 /* 123 * Setup timer to fire at 1/HZ intervals. 124 */ 125 writel(ticks_per_jiffy - 1, local_base + TIMER0_RELOAD_OFF); 126 writel(ticks_per_jiffy - 1, local_base + TIMER0_VAL_OFF); 127 128 /* 129 * Enable timer. 130 */ 131 local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | 132 TIMER0_EN | 133 TIMER0_DIV(TIMER_DIVIDER_SHIFT)); 134 } else { 135 /* 136 * Disable timer. 137 */ 138 local_timer_ctrl_clrset(TIMER0_EN, 0); 139 140 /* 141 * ACK pending timer interrupt. 142 */ 143 writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); 144 } 145} 146 147static struct clock_event_device armada_370_xp_clkevt = { 148 .name = "armada_370_xp_per_cpu_tick", 149 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, 150 .shift = 32, 151 .rating = 300, 152 .set_next_event = armada_370_xp_clkevt_next_event, 153 .set_mode = armada_370_xp_clkevt_mode, 154}; 155 156static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) 157{ 158 /* 159 * ACK timer interrupt and call event handler. 160 */ 161 struct clock_event_device *evt = *(struct clock_event_device **)dev_id; 162 163 writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); 164 evt->event_handler(evt); 165 166 return IRQ_HANDLED; 167} 168 169/* 170 * Setup the local clock events for a CPU. 171 */ 172static int armada_370_xp_timer_setup(struct clock_event_device *evt) 173{ 174 u32 clr = 0, set = 0; 175 int cpu = smp_processor_id(); 176 177 /* Use existing clock_event for cpu 0 */ 178 if (!smp_processor_id()) 179 return 0; 180 181 if (timer25Mhz) 182 set = TIMER0_25MHZ; 183 else 184 clr = TIMER0_25MHZ; 185 local_timer_ctrl_clrset(clr, set); 186 187 evt->name = armada_370_xp_clkevt.name; 188 evt->irq = armada_370_xp_clkevt.irq; 189 evt->features = armada_370_xp_clkevt.features; 190 evt->shift = armada_370_xp_clkevt.shift; 191 evt->rating = armada_370_xp_clkevt.rating, 192 evt->set_next_event = armada_370_xp_clkevt_next_event, 193 evt->set_mode = armada_370_xp_clkevt_mode, 194 evt->cpumask = cpumask_of(cpu); 195 196 *__this_cpu_ptr(percpu_armada_370_xp_evt) = evt; 197 198 clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe); 199 enable_percpu_irq(evt->irq, 0); 200 201 return 0; 202} 203 204static void armada_370_xp_timer_stop(struct clock_event_device *evt) 205{ 206 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 207 disable_percpu_irq(evt->irq); 208} 209 210static struct local_timer_ops armada_370_xp_local_timer_ops = { 211 .setup = armada_370_xp_timer_setup, 212 .stop = armada_370_xp_timer_stop, 213}; 214 215static void __init armada_370_xp_timer_init(struct device_node *np) 216{ 217 u32 clr = 0, set = 0; 218 int res; 219 220 timer_base = of_iomap(np, 0); 221 WARN_ON(!timer_base); 222 local_base = of_iomap(np, 1); 223 224 if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { 225 /* The fixed 25MHz timer is available so let's use it */ 226 set = TIMER0_25MHZ; 227 timer_clk = 25000000; 228 } else { 229 unsigned long rate = 0; 230 struct clk *clk = of_clk_get(np, 0); 231 WARN_ON(IS_ERR(clk)); 232 rate = clk_get_rate(clk); 233 timer_clk = rate / TIMER_DIVIDER; 234 235 clr = TIMER0_25MHZ; 236 timer25Mhz = false; 237 } 238 timer_ctrl_clrset(clr, set); 239 local_timer_ctrl_clrset(clr, set); 240 241 /* 242 * We use timer 0 as clocksource, and private(local) timer 0 243 * for clockevents 244 */ 245 armada_370_xp_clkevt.irq = irq_of_parse_and_map(np, 4); 246 247 ticks_per_jiffy = (timer_clk + HZ / 2) / HZ; 248 249 /* 250 * Set scale and timer for sched_clock. 251 */ 252 setup_sched_clock(armada_370_xp_read_sched_clock, 32, timer_clk); 253 254 /* 255 * Setup free-running clocksource timer (interrupts 256 * disabled). 257 */ 258 writel(0xffffffff, timer_base + TIMER0_VAL_OFF); 259 writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); 260 261 timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN | 262 TIMER0_DIV(TIMER_DIVIDER_SHIFT)); 263 264 clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, 265 "armada_370_xp_clocksource", 266 timer_clk, 300, 32, clocksource_mmio_readl_down); 267 268 /* Register the clockevent on the private timer of CPU 0 */ 269 armada_370_xp_clkevt.cpumask = cpumask_of(0); 270 clockevents_config_and_register(&armada_370_xp_clkevt, 271 timer_clk, 1, 0xfffffffe); 272 273 percpu_armada_370_xp_evt = alloc_percpu(struct clock_event_device *); 274 275 276 /* 277 * Setup clockevent timer (interrupt-driven). 278 */ 279 *__this_cpu_ptr(percpu_armada_370_xp_evt) = &armada_370_xp_clkevt; 280 res = request_percpu_irq(armada_370_xp_clkevt.irq, 281 armada_370_xp_timer_interrupt, 282 armada_370_xp_clkevt.name, 283 percpu_armada_370_xp_evt); 284 if (!res) { 285 enable_percpu_irq(armada_370_xp_clkevt.irq, 0); 286#ifdef CONFIG_LOCAL_TIMERS 287 local_timer_register(&armada_370_xp_local_timer_ops); 288#endif 289 } 290} 291CLOCKSOURCE_OF_DECLARE(armada_370_xp, "marvell,armada-370-xp-timer", 292 armada_370_xp_timer_init); 293