at91_pit.c (237130) | at91_pit.c (238370) |
---|---|
1/*- 2 * Copyright (c) 2009 Gallon Sylvestre. All rights reserved. 3 * Copyright (c) 2010 Greg Ansley. 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) 2009 Gallon Sylvestre. All rights reserved. 3 * Copyright (c) 2010 Greg Ansley. 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/at91/at91_pit.c 237130 2012-06-15 08:37:50Z imp $"); | 28__FBSDID("$FreeBSD: head/sys/arm/at91/at91_pit.c 238370 2012-07-11 17:11:54Z imp $"); |
29 30#include <sys/param.h> 31#include <sys/bus.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/resource.h> 35#include <sys/systm.h> 36#include <sys/rman.h> --- 17 unchanged lines hidden (view full) --- 54 55static struct pit_softc { 56 struct resource *mem_res; /* Memory resource */ 57 void *intrhand; /* Interrupt handle */ 58 device_t sc_dev; 59} *sc; 60 61static uint32_t timecount = 0; | 29 30#include <sys/param.h> 31#include <sys/bus.h> 32#include <sys/kernel.h> 33#include <sys/module.h> 34#include <sys/resource.h> 35#include <sys/systm.h> 36#include <sys/rman.h> --- 17 unchanged lines hidden (view full) --- 54 55static struct pit_softc { 56 struct resource *mem_res; /* Memory resource */ 57 void *intrhand; /* Interrupt handle */ 58 device_t sc_dev; 59} *sc; 60 61static uint32_t timecount = 0; |
62static unsigned at91pit_get_timecount(struct timecounter *tc); | 62static unsigned at91_pit_get_timecount(struct timecounter *tc); |
63static int pit_intr(void *arg); 64 65static inline uint32_t 66RD4(struct pit_softc *sc, bus_size_t off) 67{ 68 69 return (bus_read_4(sc->mem_res, off)); 70} 71 72static inline void 73WR4(struct pit_softc *sc, bus_size_t off, uint32_t val) 74{ 75 76 bus_write_4(sc->mem_res, off, val); 77} 78 | 63static int pit_intr(void *arg); 64 65static inline uint32_t 66RD4(struct pit_softc *sc, bus_size_t off) 67{ 68 69 return (bus_read_4(sc->mem_res, off)); 70} 71 72static inline void 73WR4(struct pit_softc *sc, bus_size_t off, uint32_t val) 74{ 75 76 bus_write_4(sc->mem_res, off, val); 77} 78 |
79static void 80at91pit_delay(int us) | 79void 80at91_pit_delay(int us) |
81{ 82 int32_t cnt, last, piv; 83 uint64_t pit_freq; 84 const uint64_t mhz = 1E6; 85 86 last = PIT_PIV(RD4(sc, PIT_PIIR)); 87 88 /* Max delay ~= 260s. @ 133Mhz */ --- 5 unchanged lines hidden (view full) --- 94 piv = PIT_PIV(RD4(sc, PIT_PIIR)); 95 cnt -= piv - last ; 96 if (piv < last) 97 cnt -= PIT_PIV(~0u) - last; 98 last = piv; 99 } 100} 101 | 81{ 82 int32_t cnt, last, piv; 83 uint64_t pit_freq; 84 const uint64_t mhz = 1E6; 85 86 last = PIT_PIV(RD4(sc, PIT_PIIR)); 87 88 /* Max delay ~= 260s. @ 133Mhz */ --- 5 unchanged lines hidden (view full) --- 94 piv = PIT_PIV(RD4(sc, PIT_PIIR)); 95 cnt -= piv - last ; 96 if (piv < last) 97 cnt -= PIT_PIV(~0u) - last; 98 last = piv; 99 } 100} 101 |
102static struct timecounter at91pit_timecounter = { 103 at91pit_get_timecount, /* get_timecount */ | 102static struct timecounter at91_pit_timecounter = { 103 at91_pit_get_timecount, /* get_timecount */ |
104 NULL, /* no poll_pps */ 105 0xffffffff, /* counter mask */ 106 0 / PIT_PRESCALE, /* frequency */ 107 "AT91SAM9 timer", /* name */ 108 1000 /* quality */ 109}; 110 111static int | 104 NULL, /* no poll_pps */ 105 0xffffffff, /* counter mask */ 106 0 / PIT_PRESCALE, /* frequency */ 107 "AT91SAM9 timer", /* name */ 108 1000 /* quality */ 109}; 110 111static int |
112at91pit_probe(device_t dev) | 112at91_pit_probe(device_t dev) |
113{ 114 115 device_set_desc(dev, "AT91SAM9 PIT"); 116 return (0); 117} 118 119static int | 113{ 114 115 device_set_desc(dev, "AT91SAM9 PIT"); 116 return (0); 117} 118 119static int |
120at91pit_attach(device_t dev) | 120at91_pit_attach(device_t dev) |
121{ 122 void *ih; 123 int rid, err = 0; 124 struct at91_softc *at91_sc; 125 struct resource *irq; 126 127 at91_sc = device_get_softc(device_get_parent(dev)); 128 sc = device_get_softc(dev); --- 14 unchanged lines hidden (view full) --- 143 err = ENOMEM; 144 goto out; 145 } 146 147 /* Activate the interrupt. */ 148 err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr, NULL, NULL, 149 &ih); 150 | 121{ 122 void *ih; 123 int rid, err = 0; 124 struct at91_softc *at91_sc; 125 struct resource *irq; 126 127 at91_sc = device_get_softc(device_get_parent(dev)); 128 sc = device_get_softc(dev); --- 14 unchanged lines hidden (view full) --- 143 err = ENOMEM; 144 goto out; 145 } 146 147 /* Activate the interrupt. */ 148 err = bus_setup_intr(dev, irq, INTR_TYPE_CLK, pit_intr, NULL, NULL, 149 &ih); 150 |
151 at91pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE; 152 tc_init(&at91pit_timecounter); | 151 at91_pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE; 152 tc_init(&at91_pit_timecounter); |
153 154 /* Enable the PIT here. */ 155 WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) | 156 PIT_EN | PIT_IEN); | 153 154 /* Enable the PIT here. */ 155 WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) | 156 PIT_EN | PIT_IEN); |
157 soc_data.delay = at91pit_delay; | |
158out: 159 return (err); 160} 161 | 157out: 158 return (err); 159} 160 |
162static device_method_t at91pit_methods[] = { 163 DEVMETHOD(device_probe, at91pit_probe), 164 DEVMETHOD(device_attach, at91pit_attach), | 161static device_method_t at91_pit_methods[] = { 162 DEVMETHOD(device_probe, at91_pit_probe), 163 DEVMETHOD(device_attach, at91_pit_attach), |
165 DEVMETHOD_END 166}; 167 | 164 DEVMETHOD_END 165}; 166 |
168static driver_t at91pit_driver = { | 167static driver_t at91_pit_driver = { |
169 "at91_pit", | 168 "at91_pit", |
170 at91pit_methods, | 169 at91_pit_methods, |
171 sizeof(struct pit_softc), 172}; 173 | 170 sizeof(struct pit_softc), 171}; 172 |
174static devclass_t at91pit_devclass; | 173static devclass_t at91_pit_devclass; |
175 | 174 |
176DRIVER_MODULE(at91_pit, atmelarm, at91pit_driver, at91pit_devclass, NULL, | 175DRIVER_MODULE(at91_pit, atmelarm, at91_pit_driver, at91_pit_devclass, NULL, |
177 NULL); 178 179static int 180pit_intr(void *arg) 181{ 182 struct trapframe *fp = arg; 183 uint32_t icnt; 184 --- 5 unchanged lines hidden (view full) --- 190 191 hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp)); 192 return (FILTER_HANDLED); 193 } 194 return (FILTER_STRAY); 195} 196 197static unsigned | 176 NULL); 177 178static int 179pit_intr(void *arg) 180{ 181 struct trapframe *fp = arg; 182 uint32_t icnt; 183 --- 5 unchanged lines hidden (view full) --- 189 190 hardclock(TRAPF_USERMODE(fp), TRAPF_PC(fp)); 191 return (FILTER_HANDLED); 192 } 193 return (FILTER_STRAY); 194} 195 196static unsigned |
198at91pit_get_timecount(struct timecounter *tc) | 197at91_pit_get_timecount(struct timecounter *tc) |
199{ 200 uint32_t piir, icnt; 201 202 piir = RD4(sc, PIT_PIIR); /* Current count | over flows */ 203 icnt = piir >> 20; /* Overflows */ 204 return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt); 205} | 198{ 199 uint32_t piir, icnt; 200 201 piir = RD4(sc, PIT_PIIR); /* Current count | over flows */ 202 icnt = piir >> 20; /* Overflows */ 203 return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt); 204} |