Deleted Added
full compact
am335x_dmtimer.c (286648) am335x_dmtimer.c (286696)
1/*-
2 * Copyright (c) 2012 Damjan Marion <dmarion@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) 2012 Damjan Marion <dmarion@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/ti/am335x/am335x_dmtimer.c 286648 2015-08-11 19:25:26Z ian $");
28__FBSDID("$FreeBSD: head/sys/arm/ti/am335x/am335x_dmtimer.c 286696 2015-08-12 19:40:32Z ian $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/conf.h>
34#include <sys/kernel.h>
35#include <sys/module.h>
36#include <sys/malloc.h>
37#include <sys/rman.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/malloc.h>
36#include <sys/rman.h>
38#include <sys/taskqueue.h>
39#include <sys/timeet.h>
37#include <sys/timeet.h>
40#include <sys/timepps.h>
41#include <sys/timetc.h>
38#include <sys/timetc.h>
42#include <sys/watchdog.h>
43#include <machine/bus.h>
39#include <machine/bus.h>
44#include <machine/cpu.h>
45#include <machine/intr.h>
46
40
47#include "opt_ntp.h"
48
49#include <dev/fdt/fdt_common.h>
50#include <dev/ofw/openfirm.h>
51#include <dev/ofw/ofw_bus.h>
52#include <dev/ofw/ofw_bus_subr.h>
53
41#include <dev/ofw/openfirm.h>
42#include <dev/ofw/ofw_bus.h>
43#include <dev/ofw/ofw_bus_subr.h>
44
54#include <machine/bus.h>
55
56#include <arm/ti/ti_prcm.h>
57#include <arm/ti/ti_hwmods.h>
45#include <arm/ti/ti_prcm.h>
46#include <arm/ti/ti_hwmods.h>
58#include <arm/ti/ti_pinmux.h>
59
47
60#define AM335X_NUM_TIMERS 8
48#include "am335x_dmtreg.h"
61
49
62#define DMT_TIDR 0x00 /* Identification Register */
63#define DMT_TIOCP_CFG 0x10 /* OCP Configuration Reg */
64#define DMT_TIOCP_RESET (1 << 0) /* TIOCP perform soft reset */
65#define DMT_IQR_EOI 0x20 /* IRQ End-Of-Interrupt Reg */
66#define DMT_IRQSTATUS_RAW 0x24 /* IRQSTATUS Raw Reg */
67#define DMT_IRQSTATUS 0x28 /* IRQSTATUS Reg */
68#define DMT_IRQENABLE_SET 0x2c /* IRQSTATUS Set Reg */
69#define DMT_IRQENABLE_CLR 0x30 /* IRQSTATUS Clear Reg */
70#define DMT_IRQWAKEEN 0x34 /* IRQ Wakeup Enable Reg */
71#define DMT_IRQ_MAT (1 << 0) /* IRQ: Match */
72#define DMT_IRQ_OVF (1 << 1) /* IRQ: Overflow */
73#define DMT_IRQ_TCAR (1 << 2) /* IRQ: Capture */
74#define DMT_IRQ_MASK (DMT_IRQ_TCAR | DMT_IRQ_OVF | DMT_IRQ_MAT)
75#define DMT_TCLR 0x38 /* Control Register */
76#define DMT_TCLR_START (1 << 0) /* Start timer */
77#define DMT_TCLR_AUTOLOAD (1 << 1) /* Auto-reload on overflow */
78#define DMT_TCLR_PRES_MASK (7 << 2) /* Prescaler mask */
79#define DMT_TCLR_PRES_ENABLE (1 << 5) /* Prescaler enable */
80#define DMT_TCLR_COMP_ENABLE (1 << 6) /* Compare enable */
81#define DMT_TCLR_PWM_HIGH (1 << 7) /* PWM default output high */
82#define DMT_TCLR_CAPTRAN_MASK (3 << 8) /* Capture transition mask */
83#define DMT_TCLR_CAPTRAN_NONE (0 << 8) /* Capture: none */
84#define DMT_TCLR_CAPTRAN_LOHI (1 << 8) /* Capture lo->hi transition */
85#define DMT_TCLR_CAPTRAN_HILO (2 << 8) /* Capture hi->lo transition */
86#define DMT_TCLR_CAPTRAN_BOTH (3 << 8) /* Capture both transitions */
87#define DMT_TCLR_TRGMODE_MASK (3 << 10) /* Trigger output mode mask */
88#define DMT_TCLR_TRGMODE_NONE (0 << 10) /* Trigger off */
89#define DMT_TCLR_TRGMODE_OVFL (1 << 10) /* Trigger on overflow */
90#define DMT_TCLR_TRGMODE_BOTH (2 << 10) /* Trigger on match + ovflow */
91#define DMT_TCLR_PWM_PTOGGLE (1 << 12) /* PWM toggles */
92#define DMT_TCLR_CAP_MODE_2ND (1 << 13) /* Capture second event mode */
93#define DMT_TCLR_GPO_CFG (1 << 14) /* (no descr in datasheet) */
94#define DMT_TCRR 0x3C /* Counter Register */
95#define DMT_TLDR 0x40 /* Load Reg */
96#define DMT_TTGR 0x44 /* Trigger Reg */
97#define DMT_TWPS 0x48 /* Write Posted Status Reg */
98#define DMT_TMAR 0x4C /* Match Reg */
99#define DMT_TCAR1 0x50 /* Capture Reg */
100#define DMT_TSICR 0x54 /* Synchr. Interface Ctrl Reg */
101#define DMT_TSICR_RESET (1 << 1) /* TSICR perform soft reset */
102#define DMT_TCAR2 0x48 /* Capture Reg */
103
104#define DMTIMER_READ4(sc, reg) (bus_read_4((sc)->tmr_mem_res, (reg)))
105#define DMTIMER_WRITE4(sc, reg, val) (bus_write_4((sc)->tmr_mem_res, (reg), (val)))
106
107struct am335x_dmtimer_softc {
108 device_t dev;
109 int tmr_mem_rid;
110 struct resource * tmr_mem_res;
111 int tmr_irq_rid;
112 struct resource * tmr_irq_res;
113 void *tmr_irq_handler;
114 uint32_t sysclk_freq;
115 uint32_t tclr; /* Cached TCLR register. */
50struct am335x_dmtimer_softc {
51 device_t dev;
52 int tmr_mem_rid;
53 struct resource * tmr_mem_res;
54 int tmr_irq_rid;
55 struct resource * tmr_irq_res;
56 void *tmr_irq_handler;
57 uint32_t sysclk_freq;
58 uint32_t tclr; /* Cached TCLR register. */
116 int pps_curmode; /* Edge mode now set in hw. */
117 struct task pps_task; /* For pps_event handling. */
118 struct cdev * pps_cdev;
119 struct pps_state pps;
120
121 union {
122 struct timecounter tc;
123 struct eventtimer et;
124 } func;
59 union {
60 struct timecounter tc;
61 struct eventtimer et;
62 } func;
63 int tmr_num; /* Hardware unit number. */
64 char tmr_name[12]; /* "DMTimerN", N = tmr_num */
125};
126
127static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
128static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
129
65};
66
67static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
68static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
69
130
131#ifdef PPS_SYNC
132/* -1 - not detected, 0 - not found, > 0 - timerX module */
133static int am335x_dmtimer_pps_module = -1;
134static const char *am335x_dmtimer_pps_hwmod = NULL;
135#endif
136
137/*
70/*
138 * PPS driver routines, included when the kernel is built with option PPS_SYNC.
139 *
140 * Note that this PPS driver does not use an interrupt. Instead it uses the
141 * hardware's ability to latch the timer's count register in response to a
142 * signal on an IO pin. Each of timers 4-7 have an associated pin, and this
143 * code allows any one of those to be used.
144 *
145 * The timecounter routines in kern_tc.c call the pps poll routine periodically
146 * to see if a new counter value has been latched. When a new value has been
147 * latched, the only processing done in the poll routine is to capture the
148 * current set of timecounter timehands (done with pps_capture()) and the
149 * latched value from the timer. The remaining work (done by pps_event()) is
150 * scheduled to be done later in a non-interrupt context.
71 * We use dmtimer2 for eventtimer and dmtimer3 for timecounter.
151 */
72 */
152#ifdef PPS_SYNC
73#define ET_TMR_NUM 2
74#define TC_TMR_NUM 3
153
75
154#define PPS_CDEV_NAME "dmtpps"
155
156static void
157am335x_dmtimer_set_capture_mode(struct am335x_dmtimer_softc *sc, bool force_off)
158{
159 int newmode;
160
161 if (force_off)
162 newmode = 0;
163 else
164 newmode = sc->pps.ppsparam.mode & PPS_CAPTUREBOTH;
165
166 if (newmode == sc->pps_curmode)
167 return;
168
169 sc->pps_curmode = newmode;
170 sc->tclr &= ~DMT_TCLR_CAPTRAN_MASK;
171 switch (newmode) {
172 case PPS_CAPTUREASSERT:
173 sc->tclr |= DMT_TCLR_CAPTRAN_LOHI;
174 break;
175 case PPS_CAPTURECLEAR:
176 sc->tclr |= DMT_TCLR_CAPTRAN_HILO;
177 break;
178 default:
179 /* It can't be BOTH, so it's disabled. */
180 break;
181 }
182 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
183}
184
185static void
186am335x_dmtimer_tc_poll_pps(struct timecounter *tc)
187{
188 struct am335x_dmtimer_softc *sc;
189
190 sc = tc->tc_priv;
191
192 /*
193 * Note that we don't have the TCAR interrupt enabled, but the hardware
194 * still provides the status bits in the "RAW" status register even when
195 * they're masked from generating an irq. However, when clearing the
196 * TCAR status to re-arm the capture for the next second, we have to
197 * write to the IRQ status register, not the RAW register. Quirky.
198 */
199 if (DMTIMER_READ4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
200 pps_capture(&sc->pps);
201 sc->pps.capcount = DMTIMER_READ4(sc, DMT_TCAR1);
202 DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
203 taskqueue_enqueue_fast(taskqueue_fast, &sc->pps_task);
204 }
205}
206
207static void
208am335x_dmtimer_process_pps_event(void *arg, int pending)
209{
210 struct am335x_dmtimer_softc *sc;
211
212 sc = arg;
213
214 /* This is the task function that gets enqueued by poll_pps. Once the
215 * time has been captured in the hw interrupt context, the remaining
216 * (more expensive) work to process the event is done later in a
217 * non-fast-interrupt context.
218 *
219 * We only support capture of the rising or falling edge, not both at
220 * once; tell the kernel to process whichever mode is currently active.
221 */
222 pps_event(&sc->pps, sc->pps.ppsparam.mode & PPS_CAPTUREBOTH);
223}
224
225static int
226am335x_dmtimer_pps_open(struct cdev *dev, int flags, int fmt,
227 struct thread *td)
228{
229 struct am335x_dmtimer_softc *sc;
230
231 sc = dev->si_drv1;
232
233 /* Enable capture on open. Harmless if already open. */
234 am335x_dmtimer_set_capture_mode(sc, 0);
235
236 return 0;
237}
238
239static int
240am335x_dmtimer_pps_close(struct cdev *dev, int flags, int fmt,
241 struct thread *td)
242{
243 struct am335x_dmtimer_softc *sc;
244
245 sc = dev->si_drv1;
246
247 /*
248 * Disable capture on last close. Use the force-off flag to override
249 * the configured mode and turn off the hardware capture.
250 */
251 am335x_dmtimer_set_capture_mode(sc, 1);
252
253 return 0;
254}
255
256static int
257am335x_dmtimer_pps_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
258 int flags, struct thread *td)
259{
260 struct am335x_dmtimer_softc *sc;
261 int err;
262
263 sc = dev->si_drv1;
264
265 /*
266 * The hardware has a "capture both edges" mode, but we can't do
267 * anything useful with it in terms of PPS capture, so don't even try.
268 */
269 if ((sc->pps.ppsparam.mode & PPS_CAPTUREBOTH) == PPS_CAPTUREBOTH)
270 return (EINVAL);
271
272 /* Let the kernel do the heavy lifting for ioctl. */
273 err = pps_ioctl(cmd, data, &sc->pps);
274 if (err != 0)
275 return (err);
276
277 /*
278 * The capture mode could have changed, set the hardware to whatever
279 * mode is now current. Effectively a no-op if nothing changed.
280 */
281 am335x_dmtimer_set_capture_mode(sc, 0);
282
283 return (err);
284}
285
286static struct cdevsw am335x_dmtimer_pps_cdevsw = {
287 .d_version = D_VERSION,
288 .d_open = am335x_dmtimer_pps_open,
289 .d_close = am335x_dmtimer_pps_close,
290 .d_ioctl = am335x_dmtimer_pps_ioctl,
291 .d_name = PPS_CDEV_NAME,
76/* List of compatible strings for FDT tree */
77static struct ofw_compat_data compat_data[] = {
78 {"ti,am335x-timer", 1},
79 {"ti,am335x-timer-1ms", 1},
80 {NULL, 0},
292};
293
81};
82
294static void
295am335x_dmtimer_pps_find()
296{
297 int i;
298 unsigned int padstate;
299 const char * padmux;
300 struct padinfo {
301 char * ballname;
302 const char * muxname;
303 int timer_num;
304 } padinfo[] = {
305 {"GPMC_ADVn_ALE", "timer4", 4},
306 {"GPMC_BEn0_CLE", "timer5", 5},
307 {"GPMC_WEn", "timer6", 6},
308 {"GPMC_OEn_REn", "timer7", 7},
309 };
83#define DMTIMER_READ4(sc, reg) bus_read_4((sc)->tmr_mem_res, (reg))
84#define DMTIMER_WRITE4(sc, reg, val) bus_write_4((sc)->tmr_mem_res, (reg), (val))
310
85
311 /*
312 * Figure out which pin the user has set up for pps. We'll use the
313 * first timer that has an external caputure pin configured as input.
314 *
315 * XXX The hieroglyphic "(padstate & (0x01 << 5)))" checks that the pin
316 * is configured for input. The right symbolic values aren't exported
317 * yet from ti_scm.h.
318 */
319 am335x_dmtimer_pps_module = 0;
320 for (i = 0; i < nitems(padinfo) && am335x_dmtimer_pps_module == 0; ++i) {
321 if (ti_pinmux_padconf_get(padinfo[i].ballname, &padmux,
322 &padstate) == 0) {
323 if (strcasecmp(padinfo[i].muxname, padmux) == 0 &&
324 (padstate & (0x01 << 5))) {
325 am335x_dmtimer_pps_module = padinfo[i].timer_num;
326 am335x_dmtimer_pps_hwmod = padinfo[i].muxname;
327 }
328 }
329 }
330
331
332 if (am335x_dmtimer_pps_module == 0) {
333 printf("am335x_dmtimer: No DMTimer found with capture pin "
334 "configured as input; PPS driver disabled.\n");
335 }
336}
337
338/*
339 * Set up the PPS cdev and the the kernel timepps stuff.
340 *
341 * Note that this routine cannot touch the hardware, because bus space resources
342 * are not fully set up yet when this is called.
343 */
344static void
345am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
346{
347 int unit;
348
349 if (am335x_dmtimer_pps_module == -1)
350 am335x_dmtimer_pps_find();
351
352 /* No PPS input */
353 if (am335x_dmtimer_pps_module == 0)
354 return;
355
356 /* Not PPS-enabled input */
357 if ((am335x_dmtimer_pps_module > 0) &&
358 (!ti_hwmods_contains(dev, am335x_dmtimer_pps_hwmod)))
359 return;
360
361 /*
362 * Indicate our capabilities (pretty much just capture of either edge).
363 * Have the kernel init its part of the pps_state struct and add its
364 * capabilities.
365 */
366 sc->pps.ppscap = PPS_CAPTUREBOTH;
367 pps_init(&sc->pps);
368
369 /*
370 * Set up to capture the PPS via timecounter polling, and init the task
371 * that does deferred pps_event() processing after capture.
372 */
373 sc->func.tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps;
374 TASK_INIT(&sc->pps_task, 0, am335x_dmtimer_process_pps_event, sc);
375
376 /* Create the PPS cdev. */
377 unit = device_get_unit(dev);
378 sc->pps_cdev = make_dev(&am335x_dmtimer_pps_cdevsw, unit,
379 UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME);
380 sc->pps_cdev->si_drv1 = sc;
381
382 device_printf(dev, "Using DMTimer%d for PPS device /dev/%s%d\n",
383 am335x_dmtimer_pps_module, PPS_CDEV_NAME, unit);
384}
385
386#endif
387
388/*
389 * End of PPS driver code.
390 */
391
392static unsigned
393am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
394{
395 struct am335x_dmtimer_softc *sc;
396
397 sc = tc->tc_priv;
398
399 return (DMTIMER_READ4(sc, DMT_TCRR));
400}
401
402static int
86static int
403am335x_dmtimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
87am335x_dmtimer_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
404{
405 struct am335x_dmtimer_softc *sc;
406 uint32_t initial_count, reload_count;
407
408 sc = et->et_priv;
409
410 /*
411 * Stop the timer before changing it. This routine will often be called

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

447 DMTIMER_WRITE4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
448 sc->tclr |= DMT_TCLR_START;
449 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
450
451 return (0);
452}
453
454static int
88{
89 struct am335x_dmtimer_softc *sc;
90 uint32_t initial_count, reload_count;
91
92 sc = et->et_priv;
93
94 /*
95 * Stop the timer before changing it. This routine will often be called

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

131 DMTIMER_WRITE4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
132 sc->tclr |= DMT_TCLR_START;
133 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
134
135 return (0);
136}
137
138static int
455am335x_dmtimer_stop(struct eventtimer *et)
139am335x_dmtimer_et_stop(struct eventtimer *et)
456{
457 struct am335x_dmtimer_softc *sc;
458
459 sc = et->et_priv;
460
461 /* Stop timer, disable and clear interrupt. */
462 sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
463 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
464 DMTIMER_WRITE4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
465 DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
466 return (0);
467}
468
469static int
140{
141 struct am335x_dmtimer_softc *sc;
142
143 sc = et->et_priv;
144
145 /* Stop timer, disable and clear interrupt. */
146 sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
147 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
148 DMTIMER_WRITE4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
149 DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
150 return (0);
151}
152
153static int
470am335x_dmtimer_intr(void *arg)
154am335x_dmtimer_et_intr(void *arg)
471{
472 struct am335x_dmtimer_softc *sc;
473
474 sc = arg;
475
476 /* Ack the interrupt, and invoke the callback if it's still enabled. */
477 DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
478 if (sc->func.et.et_active)
479 sc->func.et.et_event_cb(&sc->func.et, sc->func.et.et_arg);
480
481 return (FILTER_HANDLED);
482}
483
155{
156 struct am335x_dmtimer_softc *sc;
157
158 sc = arg;
159
160 /* Ack the interrupt, and invoke the callback if it's still enabled. */
161 DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
162 if (sc->func.et.et_active)
163 sc->func.et.et_event_cb(&sc->func.et, sc->func.et.et_arg);
164
165 return (FILTER_HANDLED);
166}
167
484/*
485 * Checks if timer is suitable to be system timer
486 */
487static int
168static int
488am335x_dmtimer_system_compatible(device_t dev)
169am335x_dmtimer_et_init(struct am335x_dmtimer_softc *sc)
489{
170{
490 phandle_t node;
171 KASSERT(am335x_dmtimer_et_sc == NULL, ("already have an eventtimer"));
491
172
492 node = ofw_bus_get_node(dev);
493 if (OF_hasprop(node, "ti,timer-alwon"))
494 return (0);
495
496 return (1);
497}
498
499static int
500am335x_dmtimer_init_et(struct am335x_dmtimer_softc *sc)
501{
502 if (am335x_dmtimer_et_sc != NULL)
503 return (EEXIST);
504
505#ifdef PPS_SYNC
506 if ((am335x_dmtimer_pps_module > 0) &&
507 (!ti_hwmods_contains(sc->dev, am335x_dmtimer_pps_hwmod))) {
508 device_printf(sc->dev, "not PPS enabled\n");
509 return (ENXIO);
510 }
511#endif
512
513 /* Setup eventtimer interrupt handler. */
173 /*
174 * Setup eventtimer interrupt handling. Panic if anything goes wrong,
175 * because the system just isn't going to run without an eventtimer.
176 */
177 sc->tmr_irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ,
178 &sc->tmr_irq_rid, RF_ACTIVE);
179 if (sc->tmr_irq_res == NULL)
180 panic("am335x_dmtimer: could not allocate irq resources");
514 if (bus_setup_intr(sc->dev, sc->tmr_irq_res, INTR_TYPE_CLK,
181 if (bus_setup_intr(sc->dev, sc->tmr_irq_res, INTR_TYPE_CLK,
515 am335x_dmtimer_intr, NULL, sc, &sc->tmr_irq_handler) != 0) {
516 device_printf(sc->dev, "Unable to setup the clock irq handler.\n");
517 return (ENXIO);
518 }
182 am335x_dmtimer_et_intr, NULL, sc, &sc->tmr_irq_handler) != 0)
183 panic("am335x_dmtimer: count not setup irq handler");
519
184
520 sc->func.et.et_name = "AM335x Eventtimer";
185 sc->func.et.et_name = sc->tmr_name;
521 sc->func.et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
186 sc->func.et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
522 sc->func.et.et_quality = 1000;
187 sc->func.et.et_quality = 500;
523 sc->func.et.et_frequency = sc->sysclk_freq;
524 sc->func.et.et_min_period =
525 ((0x00000005LLU << 32) / sc->func.et.et_frequency);
526 sc->func.et.et_max_period =
527 (0xfffffffeLLU << 32) / sc->func.et.et_frequency;
188 sc->func.et.et_frequency = sc->sysclk_freq;
189 sc->func.et.et_min_period =
190 ((0x00000005LLU << 32) / sc->func.et.et_frequency);
191 sc->func.et.et_max_period =
192 (0xfffffffeLLU << 32) / sc->func.et.et_frequency;
528 sc->func.et.et_start = am335x_dmtimer_start;
529 sc->func.et.et_stop = am335x_dmtimer_stop;
193 sc->func.et.et_start = am335x_dmtimer_et_start;
194 sc->func.et.et_stop = am335x_dmtimer_et_stop;
530 sc->func.et.et_priv = sc;
195 sc->func.et.et_priv = sc;
531 et_register(&sc->func.et);
532
533 am335x_dmtimer_et_sc = sc;
196
197 am335x_dmtimer_et_sc = sc;
198 et_register(&sc->func.et);
534
535 return (0);
536}
537
199
200 return (0);
201}
202
203static unsigned
204am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
205{
206 struct am335x_dmtimer_softc *sc;
207
208 sc = tc->tc_priv;
209
210 return (DMTIMER_READ4(sc, DMT_TCRR));
211}
212
538static int
213static int
539am335x_dmtimer_init_tc(struct am335x_dmtimer_softc *sc)
214am335x_dmtimer_tc_init(struct am335x_dmtimer_softc *sc)
540{
215{
541 if (am335x_dmtimer_tc_sc != NULL)
542 return (EEXIST);
216 KASSERT(am335x_dmtimer_tc_sc == NULL, ("already have a timecounter"));
543
544 /* Set up timecounter, start it, register it. */
545 DMTIMER_WRITE4(sc, DMT_TSICR, DMT_TSICR_RESET);
546 while (DMTIMER_READ4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
547 continue;
548
549 sc->tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
550 DMTIMER_WRITE4(sc, DMT_TLDR, 0);
551 DMTIMER_WRITE4(sc, DMT_TCRR, 0);
552 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
553
217
218 /* Set up timecounter, start it, register it. */
219 DMTIMER_WRITE4(sc, DMT_TSICR, DMT_TSICR_RESET);
220 while (DMTIMER_READ4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
221 continue;
222
223 sc->tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
224 DMTIMER_WRITE4(sc, DMT_TLDR, 0);
225 DMTIMER_WRITE4(sc, DMT_TCRR, 0);
226 DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
227
554 sc->func.tc.tc_name = "AM335x Timecounter";
228 sc->func.tc.tc_name = sc->tmr_name;
555 sc->func.tc.tc_get_timecount = am335x_dmtimer_tc_get_timecount;
556 sc->func.tc.tc_counter_mask = ~0u;
557 sc->func.tc.tc_frequency = sc->sysclk_freq;
229 sc->func.tc.tc_get_timecount = am335x_dmtimer_tc_get_timecount;
230 sc->func.tc.tc_counter_mask = ~0u;
231 sc->func.tc.tc_frequency = sc->sysclk_freq;
558 sc->func.tc.tc_quality = 1000;
232 sc->func.tc.tc_quality = 500;
559 sc->func.tc.tc_priv = sc;
233 sc->func.tc.tc_priv = sc;
560 tc_init(&sc->func.tc);
561
562 am335x_dmtimer_tc_sc = sc;
234
235 am335x_dmtimer_tc_sc = sc;
236 tc_init(&sc->func.tc);
563
564 return (0);
565}
566
567static int
568am335x_dmtimer_probe(device_t dev)
569{
237
238 return (0);
239}
240
241static int
242am335x_dmtimer_probe(device_t dev)
243{
244 char strbuf[32];
245 int tmr_num;
570
571 if (!ofw_bus_status_okay(dev))
572 return (ENXIO);
573
246
247 if (!ofw_bus_status_okay(dev))
248 return (ENXIO);
249
574 if (ofw_bus_is_compatible(dev, "ti,am335x-timer-1ms") ||
575 ofw_bus_is_compatible(dev, "ti,am335x-timer")) {
576 device_set_desc(dev, "AM335x DMTimer");
577 return(BUS_PROBE_DEFAULT);
578 }
250 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
251 return (ENXIO);
579
252
580 return (ENXIO);
253 /*
254 * Get the hardware unit number (the N from ti,hwmods="timerN").
255 * If this isn't the hardware unit we're going to use for either the
256 * eventtimer or the timecounter, no point in instantiating the device.
257 */
258 tmr_num = ti_hwmods_get_unit(dev, "timer");
259 if (tmr_num != ET_TMR_NUM && tmr_num != TC_TMR_NUM)
260 return (ENXIO);
261
262 snprintf(strbuf, sizeof(strbuf), "AM335x DMTimer%d", tmr_num);
263 device_set_desc_copy(dev, strbuf);
264
265 return(BUS_PROBE_DEFAULT);
581}
582
583static int
584am335x_dmtimer_attach(device_t dev)
585{
586 struct am335x_dmtimer_softc *sc;
266}
267
268static int
269am335x_dmtimer_attach(device_t dev)
270{
271 struct am335x_dmtimer_softc *sc;
587 int err;
588 clk_ident_t timer_id;
272 clk_ident_t timer_id;
589 int enable;
273 int err;
590
591 sc = device_get_softc(dev);
592 sc->dev = dev;
593
594 /* Get the base clock frequency. */
274
275 sc = device_get_softc(dev);
276 sc->dev = dev;
277
278 /* Get the base clock frequency. */
595 err = ti_prcm_clk_get_source_freq(SYS_CLK, &sc->sysclk_freq);
596 if (err) {
597 device_printf(dev, "Error: could not get sysclk frequency\n");
279 if ((err = ti_prcm_clk_get_source_freq(SYS_CLK, &sc->sysclk_freq)) != 0)
280 return (err);
281
282 /* Enable clocks and power on the device. */
283 if ((timer_id = ti_hwmods_get_clock(dev)) == INVALID_CLK_IDENT)
598 return (ENXIO);
284 return (ENXIO);
599 }
285 if ((err = ti_prcm_clk_set_source(timer_id, SYSCLK_CLK)) != 0)
286 return (err);
287 if ((err = ti_prcm_clk_enable(timer_id)) != 0)
288 return (err);
600
601 /* Request the memory resources. */
602 sc->tmr_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
603 &sc->tmr_mem_rid, RF_ACTIVE);
604 if (sc->tmr_mem_res == NULL) {
289
290 /* Request the memory resources. */
291 sc->tmr_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
292 &sc->tmr_mem_rid, RF_ACTIVE);
293 if (sc->tmr_mem_res == NULL) {
605 device_printf(dev, "Error: could not allocate mem resources\n");
606 return (ENXIO);
607 }
608
294 return (ENXIO);
295 }
296
609 /* Request the IRQ resources. */
610 sc->tmr_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
611 &sc->tmr_irq_rid, RF_ACTIVE);
612 if (err) {
613 bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
614 sc->tmr_mem_res);
615 device_printf(dev, "Error: could not allocate irq resources\n");
616 return (ENXIO);
617 }
297 sc->tmr_num = ti_hwmods_get_unit(dev, "timer");
298 snprintf(sc->tmr_name, sizeof(sc->tmr_name), "DMTimer%d", sc->tmr_num);
618
299
619#ifdef PPS_SYNC
620 am335x_dmtimer_pps_init(dev, sc);
621#endif
300 /*
301 * Go set up either a timecounter or eventtimer. We wouldn't have
302 * attached if we weren't one or the other.
303 */
304 if (sc->tmr_num == ET_TMR_NUM)
305 am335x_dmtimer_et_init(sc);
306 else if (sc->tmr_num == TC_TMR_NUM)
307 am335x_dmtimer_tc_init(sc);
308 else
309 panic("am335x_dmtimer: bad timer number %d", sc->tmr_num);
622
310
623 enable = 0;
624 /* Try to use as a timecounter or event timer */
625 if (am335x_dmtimer_system_compatible(dev)) {
626 if (am335x_dmtimer_init_tc(sc) == 0)
627 enable = 1;
628 else if (am335x_dmtimer_init_et(sc) == 0)
629 enable = 1;
630 }
631
632 if (enable) {
633 /* Enable clocks and power on the chosen devices. */
634 timer_id = ti_hwmods_get_clock(dev);
635 if (timer_id == INVALID_CLK_IDENT) {
636 bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
637 sc->tmr_mem_res);
638 bus_release_resource(dev, SYS_RES_IRQ, sc->tmr_irq_rid,
639 sc->tmr_irq_res);
640 device_printf(dev, "failed to get device id using ti,hwmods\n");
641 return (ENXIO);
642 }
643
644 err = ti_prcm_clk_set_source(timer_id, SYSCLK_CLK);
645 err |= ti_prcm_clk_enable(timer_id);
646
647 if (err) {
648 bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
649 sc->tmr_mem_res);
650 bus_release_resource(dev, SYS_RES_IRQ, sc->tmr_irq_rid,
651 sc->tmr_irq_res);
652 device_printf(dev, "Error: could not enable timer clock\n");
653 return (ENXIO);
654 }
655 }
656
657 return (0);
658}
659
660static device_method_t am335x_dmtimer_methods[] = {
661 DEVMETHOD(device_probe, am335x_dmtimer_probe),
662 DEVMETHOD(device_attach, am335x_dmtimer_attach),
663 { 0, 0 }
664};

--- 45 unchanged lines hidden ---
311 return (0);
312}
313
314static device_method_t am335x_dmtimer_methods[] = {
315 DEVMETHOD(device_probe, am335x_dmtimer_probe),
316 DEVMETHOD(device_attach, am335x_dmtimer_attach),
317 { 0, 0 }
318};

--- 45 unchanged lines hidden ---