Deleted Added
full compact
at91_pit.c (237115) at91_pit.c (237130)
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 237115 2012-06-15 06:38:55Z imp $");
28__FBSDID("$FreeBSD: head/sys/arm/at91/at91_pit.c 237130 2012-06-15 08:37:50Z 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>

--- 6 unchanged lines hidden (view full) ---

43#include <machine/cpufunc.h>
44#include <machine/frame.h>
45#include <machine/intr.h>
46#include <machine/resource.h>
47
48#include <arm/at91/at91var.h>
49#include <arm/at91/at91_pitreg.h>
50
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>

--- 6 unchanged lines hidden (view full) ---

43#include <machine/cpufunc.h>
44#include <machine/frame.h>
45#include <machine/intr.h>
46#include <machine/resource.h>
47
48#include <arm/at91/at91var.h>
49#include <arm/at91/at91_pitreg.h>
50
51#ifndef PIT_PRESCALE
52#define PIT_PRESCALE (16)
53#endif
54
51static struct pit_softc {
52 struct resource *mem_res; /* Memory resource */
53 void *intrhand; /* Interrupt handle */
54 device_t sc_dev;
55} *sc;
56
57static uint32_t timecount = 0;
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);
63static int pit_intr(void *arg);
58
59static inline uint32_t
60RD4(struct pit_softc *sc, bus_size_t off)
61{
62
63 return (bus_read_4(sc->mem_res, off));
64}
65
66static inline void
67WR4(struct pit_softc *sc, bus_size_t off, uint32_t val)
68{
69
70 bus_write_4(sc->mem_res, off, val);
71}
72
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
73static unsigned at91pit_get_timecount(struct timecounter *tc);
74static int pit_intr(void *arg);
79static void
80at91pit_delay(int us)
81{
82 int32_t cnt, last, piv;
83 uint64_t pit_freq;
84 const uint64_t mhz = 1E6;
75
85
76#ifndef PIT_PRESCALE
77#define PIT_PRESCALE (16)
78#endif
86 last = PIT_PIV(RD4(sc, PIT_PIIR));
79
87
88 /* Max delay ~= 260s. @ 133Mhz */
89 pit_freq = at91_master_clock / PIT_PRESCALE;
90 cnt = ((pit_freq * us) + (mhz -1)) / mhz;
91 cnt = (cnt <= 0) ? 1 : cnt;
92
93 while (cnt > 0) {
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
80static struct timecounter at91pit_timecounter = {
81 at91pit_get_timecount, /* get_timecount */
82 NULL, /* no poll_pps */
83 0xffffffff, /* counter mask */
84 0 / PIT_PRESCALE, /* frequency */
85 "AT91SAM9 timer", /* name */
86 1000 /* quality */
87};
88
89static int
90at91pit_probe(device_t dev)
91{
92
102static struct timecounter at91pit_timecounter = {
103 at91pit_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
112at91pit_probe(device_t dev)
113{
114
93 if (at91_is_sam9() || at91_is_sam9xe()) {
94 device_set_desc(dev, "AT91SAM9 PIT");
95 return (0);
96 }
97 return (ENXIO);
115 device_set_desc(dev, "AT91SAM9 PIT");
116 return (0);
98}
99
100static int
101at91pit_attach(device_t dev)
102{
103 void *ih;
104 int rid, err = 0;
105 struct at91_softc *at91_sc;

--- 24 unchanged lines hidden (view full) ---

130 &ih);
131
132 at91pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
133 tc_init(&at91pit_timecounter);
134
135 /* Enable the PIT here. */
136 WR4(sc, PIT_MR, PIT_PIV(at91_master_clock / PIT_PRESCALE / hz) |
137 PIT_EN | PIT_IEN);
117}
118
119static int
120at91pit_attach(device_t dev)
121{
122 void *ih;
123 int rid, err = 0;
124 struct at91_softc *at91_sc;

--- 24 unchanged lines hidden (view full) ---

149 &ih);
150
151 at91pit_timecounter.tc_frequency = at91_master_clock / PIT_PRESCALE;
152 tc_init(&at91pit_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);
157 soc_data.delay = at91pit_delay;
138out:
139 return (err);
140}
141
142static device_method_t at91pit_methods[] = {
143 DEVMETHOD(device_probe, at91pit_probe),
144 DEVMETHOD(device_attach, at91pit_attach),
145 DEVMETHOD_END

--- 32 unchanged lines hidden (view full) ---

178at91pit_get_timecount(struct timecounter *tc)
179{
180 uint32_t piir, icnt;
181
182 piir = RD4(sc, PIT_PIIR); /* Current count | over flows */
183 icnt = piir >> 20; /* Overflows */
184 return (timecount + PIT_PIV(piir) + PIT_PIV(RD4(sc, PIT_MR)) * icnt);
185}
158out:
159 return (err);
160}
161
162static device_method_t at91pit_methods[] = {
163 DEVMETHOD(device_probe, at91pit_probe),
164 DEVMETHOD(device_attach, at91pit_attach),
165 DEVMETHOD_END

--- 32 unchanged lines hidden (view full) ---

198at91pit_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}
186
187void
188DELAY(int us)
189{
190 int32_t cnt, last, piv;
191 uint64_t pit_freq;
192 const uint64_t mhz = 1E6;
193
194 last = PIT_PIV(RD4(sc, PIT_PIIR));
195
196 /* Max delay ~= 260s. @ 133Mhz */
197 pit_freq = at91_master_clock / PIT_PRESCALE;
198 cnt = ((pit_freq * us) + (mhz -1)) / mhz;
199 cnt = (cnt <= 0) ? 1 : cnt;
200
201 while (cnt > 0) {
202 piv = PIT_PIV(RD4(sc, PIT_PIIR));
203 cnt -= piv - last ;
204 if (piv < last)
205 cnt -= PIT_PIV(~0u) - last;
206 last = piv;
207 }
208}