lpc_timer.c (239278) | lpc_timer.c (247463) |
---|---|
1/*- 2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/arm/lpc/lpc_timer.c 239278 2012-08-15 05:37:10Z gonzo $"); | 28__FBSDID("$FreeBSD: head/sys/arm/lpc/lpc_timer.c 247463 2013-02-28 13:46:03Z mav $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/module.h> 35#include <sys/malloc.h> 36#include <sys/rman.h> --- 30 unchanged lines hidden (view full) --- 67 { SYS_RES_IRQ, 1, RF_ACTIVE }, 68 { -1, 0 } 69}; 70 71static struct lpc_timer_softc *timer_softc = NULL; 72static int lpc_timer_initialized = 0; 73static int lpc_timer_probe(device_t); 74static int lpc_timer_attach(device_t); | 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/module.h> 35#include <sys/malloc.h> 36#include <sys/rman.h> --- 30 unchanged lines hidden (view full) --- 67 { SYS_RES_IRQ, 1, RF_ACTIVE }, 68 { -1, 0 } 69}; 70 71static struct lpc_timer_softc *timer_softc = NULL; 72static int lpc_timer_initialized = 0; 73static int lpc_timer_probe(device_t); 74static int lpc_timer_attach(device_t); |
75static int lpc_timer_start(struct eventtimer *, struct bintime *first, 76 struct bintime *); | 75static int lpc_timer_start(struct eventtimer *, 76 sbintime_t first, sbintime_t period); |
77static int lpc_timer_stop(struct eventtimer *et); 78static unsigned lpc_get_timecount(struct timecounter *); 79static int lpc_hardclock(void *); 80 81#define timer0_read_4(sc, reg) \ 82 bus_space_read_4(sc->lt_bst0, sc->lt_bsh0, reg) 83#define timer0_write_4(sc, reg, val) \ 84 bus_space_write_4(sc->lt_bst0, sc->lt_bsh0, reg, val) --- 83 unchanged lines hidden (view full) --- 168 169 /* Set desired frequency in event timer and timecounter */ 170 sc->lt_et.et_frequency = (uint64_t)freq; 171 lpc_timecounter.tc_frequency = (uint64_t)freq; 172 173 sc->lt_et.et_name = "LPC32x0 Timer0"; 174 sc->lt_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT; 175 sc->lt_et.et_quality = 1000; | 77static int lpc_timer_stop(struct eventtimer *et); 78static unsigned lpc_get_timecount(struct timecounter *); 79static int lpc_hardclock(void *); 80 81#define timer0_read_4(sc, reg) \ 82 bus_space_read_4(sc->lt_bst0, sc->lt_bsh0, reg) 83#define timer0_write_4(sc, reg, val) \ 84 bus_space_write_4(sc->lt_bst0, sc->lt_bsh0, reg, val) --- 83 unchanged lines hidden (view full) --- 168 169 /* Set desired frequency in event timer and timecounter */ 170 sc->lt_et.et_frequency = (uint64_t)freq; 171 lpc_timecounter.tc_frequency = (uint64_t)freq; 172 173 sc->lt_et.et_name = "LPC32x0 Timer0"; 174 sc->lt_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT; 175 sc->lt_et.et_quality = 1000; |
176 sc->lt_et.et_min_period.sec = 0; 177 sc->lt_et.et_min_period.frac = 178 ((0x00000002LLU << 32) / sc->lt_et.et_frequency) << 32; 179 sc->lt_et.et_max_period.sec = 0xfffffff0U / sc->lt_et.et_frequency; 180 sc->lt_et.et_max_period.frac = 181 ((0xfffffffeLLU << 32) / sc->lt_et.et_frequency) << 32; | 176 sc->lt_et.et_min_period = (0x00000002LLU << 32) / sc->lt_et.et_frequency; 177 sc->lt_et.et_max_period = (0xfffffffeLLU << 32) / sc->lt_et.et_frequency; |
182 sc->lt_et.et_start = lpc_timer_start; 183 sc->lt_et.et_stop = lpc_timer_stop; 184 sc->lt_et.et_priv = sc; 185 186 et_register(&sc->lt_et); 187 tc_init(&lpc_timecounter); 188 189 /* Reset and enable timecounter */ --- 4 unchanged lines hidden (view full) --- 194 195 /* DELAY() now can work properly */ 196 lpc_timer_initialized = 1; 197 198 return (0); 199} 200 201static int | 178 sc->lt_et.et_start = lpc_timer_start; 179 sc->lt_et.et_stop = lpc_timer_stop; 180 sc->lt_et.et_priv = sc; 181 182 et_register(&sc->lt_et); 183 tc_init(&lpc_timecounter); 184 185 /* Reset and enable timecounter */ --- 4 unchanged lines hidden (view full) --- 190 191 /* DELAY() now can work properly */ 192 lpc_timer_initialized = 1; 193 194 return (0); 195} 196 197static int |
202lpc_timer_start(struct eventtimer *et, struct bintime *first, 203 struct bintime *period) | 198lpc_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period) |
204{ 205 struct lpc_timer_softc *sc = (struct lpc_timer_softc *)et->et_priv; 206 uint32_t ticks; 207 | 199{ 200 struct lpc_timer_softc *sc = (struct lpc_timer_softc *)et->et_priv; 201 uint32_t ticks; 202 |
208 if (period == NULL) | 203 if (period == 0) { |
209 sc->lt_oneshot = 1; | 204 sc->lt_oneshot = 1; |
210 else { | 205 sc->lt_period = 0; 206 } else { |
211 sc->lt_oneshot = 0; | 207 sc->lt_oneshot = 0; |
212 sc->lt_period = (sc->lt_et.et_frequency * (first->frac >> 32)) >> 32; 213 sc->lt_period += sc->lt_et.et_frequency * first->sec; | 208 sc->lt_period = ((uint32_t)et->et_frequency * period) >> 32; |
214 } 215 | 209 } 210 |
216 if (first == NULL) | 211 if (first == 0) |
217 ticks = sc->lt_period; | 212 ticks = sc->lt_period; |
218 else { 219 ticks = (sc->lt_et.et_frequency * (first->frac >> 32)) >> 32; 220 if (first->sec != 0) 221 ticks += sc->lt_et.et_frequency * first->sec; 222 } | 213 else 214 ticks = ((uint32_t)et->et_frequency * first) >> 32; |
223 224 /* Reset timer */ 225 timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_RESET); 226 timer0_write_4(sc, LPC_TIMER_TCR, 0); 227 228 /* Start timer */ 229 timer0_clear(sc); 230 timer0_write_4(sc, LPC_TIMER_MR0, ticks); --- 90 unchanged lines hidden --- | 215 216 /* Reset timer */ 217 timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_RESET); 218 timer0_write_4(sc, LPC_TIMER_TCR, 0); 219 220 /* Start timer */ 221 timer0_clear(sc); 222 timer0_write_4(sc, LPC_TIMER_MR0, ticks); --- 90 unchanged lines hidden --- |