1 /* 2 * linux/arch/arm/mach-mmp/time.c 3 * 4 * Support for clocksource and clockevents 5 * 6 * Copyright (C) 2008 Marvell International Ltd. 7 * All rights reserved. 8 * 9 * 2008-04-11: Jason Chagas <Jason.chagas@marvell.com> 10 * 2008-10-08: Bin Yang <bin.yang@marvell.com> 11 * 12 * The timers module actually includes three timers, each timer with upto 13 * three match comparators. Timer #0 is used here in free-running mode as 14 * the clock source, and match comparator #1 used as clock event device. 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License version 2 as 18 * published by the Free Software Foundation. 19 */ 20 21 #include <linux/init.h> 22 #include <linux/kernel.h> 23 #include <linux/interrupt.h> 24 #include <linux/clockchips.h> 25 26 #include <linux/io.h> 27 #include <linux/irq.h> 28 #include <linux/sched.h> 29 #include <linux/cnt32_to_63.h> 30 31 #include <mach/addr-map.h> 32 #include <mach/regs-timers.h> 33 #include <mach/regs-apbc.h> 34 #include <mach/irqs.h> 35 #include <mach/cputype.h> 36 #include <asm/mach/time.h> 37 38 #include "clock.h" 39 40 #define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE 41 42 #define MAX_DELTA (0xfffffffe) 43 #define MIN_DELTA (16) 44 45 #define TCR2NS_SCALE_FACTOR 10 46 47 static unsigned long tcr2ns_scale; 48 49 static void __init set_tcr2ns_scale(unsigned long tcr_rate) 50 { 51 unsigned long long v = 1000000000ULL << TCR2NS_SCALE_FACTOR; 52 do_div(v, tcr_rate); 53 tcr2ns_scale = v; 54 /* 55 * We want an even value to automatically clear the top bit 56 * returned by cnt32_to_63() without an additional run time 57 * instruction. So if the LSB is 1 then round it up. 58 */ 59 if (tcr2ns_scale & 1) 60 tcr2ns_scale++; 61 } 62 63 /* 64 * FIXME: the timer needs some delay to stablize the counter capture 65 */ 66 static inline uint32_t timer_read(void) 67 { 68 int delay = 100; 69 70 __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0)); 71 72 while (delay--) 73 cpu_relax(); 74 75 return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); 76 } 77 78 unsigned long long sched_clock(void) 79 { 80 unsigned long long v = cnt32_to_63(timer_read()); 81 return (v * tcr2ns_scale) >> TCR2NS_SCALE_FACTOR; 82 } 83 84 static irqreturn_t timer_interrupt(int irq, void *dev_id) 85 { 86 struct clock_event_device *c = dev_id; 87 88 /* disable and clear pending interrupt status */ 89 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); 90 __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0)); 91 c->event_handler(c); 92 return IRQ_HANDLED; 93 } 94 95 static int timer_set_next_event(unsigned long delta, 96 struct clock_event_device *dev) 97 { 98 unsigned long flags, next; 99 100 local_irq_save(flags); 101 102 /* clear pending interrupt status and enable */ 103 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); 104 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); 105 106 next = timer_read() + delta; 107 __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); 108 109 local_irq_restore(flags); 110 return 0; 111 } 112 113 static void timer_set_mode(enum clock_event_mode mode, 114 struct clock_event_device *dev) 115 { 116 unsigned long flags; 117 118 local_irq_save(flags); 119 switch (mode) { 120 case CLOCK_EVT_MODE_ONESHOT: 121 case CLOCK_EVT_MODE_UNUSED: 122 case CLOCK_EVT_MODE_SHUTDOWN: 123 /* disable the matching interrupt */ 124 __raw_writel(0x00, TIMERS_VIRT_BASE + TMR_IER(0)); 125 break; 126 case CLOCK_EVT_MODE_RESUME: 127 case CLOCK_EVT_MODE_PERIODIC: 128 break; 129 } 130 local_irq_restore(flags); 131 } 132 133 static struct clock_event_device ckevt = { 134 .name = "clockevent", 135 .features = CLOCK_EVT_FEAT_ONESHOT, 136 .shift = 32, 137 .rating = 200, 138 .set_next_event = timer_set_next_event, 139 .set_mode = timer_set_mode, 140 }; 141 142 static cycle_t clksrc_read(struct clocksource *cs) 143 { 144 return timer_read(); 145 } 146 147 static struct clocksource cksrc = { 148 .name = "clocksource", 149 .shift = 20, 150 .rating = 200, 151 .read = clksrc_read, 152 .mask = CLOCKSOURCE_MASK(32), 153 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 154 }; 155 156 static void __init timer_config(void) 157 { 158 uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); 159 uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER); 160 uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR); 161 162 __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */ 163 164 ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3); 165 __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); 166 167 /* free-running mode */ 168 __raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR); 169 170 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */ 171 __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ 172 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); 173 174 /* enable timer counter */ 175 __raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER); 176 } 177 178 static struct irqaction timer_irq = { 179 .name = "timer", 180 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 181 .handler = timer_interrupt, 182 .dev_id = &ckevt, 183 }; 184 185 void __init timer_init(int irq) 186 { 187 timer_config(); 188 189 set_tcr2ns_scale(CLOCK_TICK_RATE); 190 191 ckevt.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt.shift); 192 ckevt.max_delta_ns = clockevent_delta2ns(MAX_DELTA, &ckevt); 193 ckevt.min_delta_ns = clockevent_delta2ns(MIN_DELTA, &ckevt); 194 ckevt.cpumask = cpumask_of(0); 195 196 cksrc.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc.shift); 197 198 setup_irq(irq, &timer_irq); 199 200 clocksource_register(&cksrc); 201 clockevents_register_device(&ckevt); 202 } 203 204 static void __init mmp2_timer_init(void) 205 { 206 unsigned long clk_rst; 207 208 __raw_writel(APBC_APBCLK | APBC_RST, APBC_MMP2_TIMERS); 209 210 /* 211 * enable bus/functional clock, enable 6.5MHz (divider 4), 212 * release reset 213 */ 214 clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1); 215 __raw_writel(clk_rst, APBC_MMP2_TIMERS); 216 217 timer_init(IRQ_MMP2_TIMER1); 218 } 219 220 struct sys_timer mmp2_timer = { 221 .init = mmp2_timer_init, 222 }; 223 224