am335x_dmtimer.c revision 286648
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
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
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 $");
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>
38#include <sys/taskqueue.h>
39#include <sys/timeet.h>
40#include <sys/timepps.h>
41#include <sys/timetc.h>
42#include <sys/watchdog.h>
43#include <machine/bus.h>
44#include <machine/cpu.h>
45#include <machine/intr.h>
46
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
54#include <machine/bus.h>
55
56#include <arm/ti/ti_prcm.h>
57#include <arm/ti/ti_hwmods.h>
58#include <arm/ti/ti_pinmux.h>
59
60#define	AM335X_NUM_TIMERS	8
61
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. */
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;
125};
126
127static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
128static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
129
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/*
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.
151 */
152#ifdef PPS_SYNC
153
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,
292};
293
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	};
310
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
403am335x_dmtimer_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
412	 * while the timer is still running, to either lengthen or shorten the
413	 * current event time.  We need to ensure the timer doesn't expire while
414	 * we're working with it.
415	 *
416	 * Also clear any pending interrupt status, because it's at least
417	 * theoretically possible that we're running in a primary interrupt
418	 * context now, and a timer interrupt could be pending even before we
419	 * stopped the timer.  The more likely case is that we're being called
420	 * from the et_event_cb() routine dispatched from our own handler, but
421	 * it's not clear to me that that's the only case possible.
422	 */
423	sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
424	DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
425	DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
426
427	if (period != 0) {
428		reload_count = ((uint32_t)et->et_frequency * period) >> 32;
429		sc->tclr |= DMT_TCLR_AUTOLOAD;
430	} else {
431		reload_count = 0;
432	}
433
434	if (first != 0)
435		initial_count = ((uint32_t)et->et_frequency * first) >> 32;
436	else
437		initial_count = reload_count;
438
439	/*
440	 * Set auto-reload and current-count values.  This timer hardware counts
441	 * up from the initial/reload value and interrupts on the zero rollover.
442	 */
443	DMTIMER_WRITE4(sc, DMT_TLDR, 0xFFFFFFFF - reload_count);
444	DMTIMER_WRITE4(sc, DMT_TCRR, 0xFFFFFFFF - initial_count);
445
446	/* Enable overflow interrupt, and start the timer. */
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
455am335x_dmtimer_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
470am335x_dmtimer_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
484/*
485 * Checks if timer is suitable to be system timer
486 */
487static int
488am335x_dmtimer_system_compatible(device_t dev)
489{
490	phandle_t node;
491
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. */
514	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	}
519
520	sc->func.et.et_name = "AM335x Eventtimer";
521	sc->func.et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
522	sc->func.et.et_quality = 1000;
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;
528	sc->func.et.et_start = am335x_dmtimer_start;
529	sc->func.et.et_stop = am335x_dmtimer_stop;
530	sc->func.et.et_priv = sc;
531	et_register(&sc->func.et);
532
533	am335x_dmtimer_et_sc = sc;
534
535	return (0);
536}
537
538static int
539am335x_dmtimer_init_tc(struct am335x_dmtimer_softc *sc)
540{
541	if (am335x_dmtimer_tc_sc != NULL)
542		return (EEXIST);
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
554	sc->func.tc.tc_name           = "AM335x Timecounter";
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;
558	sc->func.tc.tc_quality        = 1000;
559	sc->func.tc.tc_priv           = sc;
560	tc_init(&sc->func.tc);
561
562	am335x_dmtimer_tc_sc = sc;
563
564	return (0);
565}
566
567static int
568am335x_dmtimer_probe(device_t dev)
569{
570
571	if (!ofw_bus_status_okay(dev))
572		return (ENXIO);
573
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	}
579
580	return (ENXIO);
581}
582
583static int
584am335x_dmtimer_attach(device_t dev)
585{
586	struct am335x_dmtimer_softc *sc;
587	int err;
588	clk_ident_t timer_id;
589	int enable;
590
591	sc = device_get_softc(dev);
592	sc->dev = dev;
593
594	/* 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");
598		return (ENXIO);
599	}
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) {
605		device_printf(dev, "Error: could not allocate mem resources\n");
606		return (ENXIO);
607	}
608
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	}
618
619#ifdef PPS_SYNC
620	am335x_dmtimer_pps_init(dev, sc);
621#endif
622
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};
665
666static driver_t am335x_dmtimer_driver = {
667	"am335x_dmtimer",
668	am335x_dmtimer_methods,
669	sizeof(struct am335x_dmtimer_softc),
670};
671
672static devclass_t am335x_dmtimer_devclass;
673
674DRIVER_MODULE(am335x_dmtimer, simplebus, am335x_dmtimer_driver, am335x_dmtimer_devclass, 0, 0);
675MODULE_DEPEND(am335x_dmtimer, am335x_prcm, 1, 1, 1);
676
677void
678DELAY(int usec)
679{
680	struct am335x_dmtimer_softc *sc;
681	int32_t counts;
682	uint32_t first, last;
683
684	sc = am335x_dmtimer_tc_sc;
685
686	if (sc == NULL) {
687		for (; usec > 0; usec--)
688			for (counts = 200; counts > 0; counts--)
689				/* Prevent gcc from optimizing  out the loop */
690				cpufunc_nullop();
691		return;
692	}
693
694	/* Get the number of times to count */
695	counts = (usec + 1) * (sc->sysclk_freq / 1000000);
696
697	first = DMTIMER_READ4(sc, DMT_TCRR);
698
699	while (counts > 0) {
700		last = DMTIMER_READ4(sc, DMT_TCRR);
701		if (last > first) {
702			counts -= (int32_t)(last - first);
703		} else {
704			counts -= (int32_t)((0xFFFFFFFF - first) + last);
705		}
706		first = last;
707	}
708}
709
710