xref: /freebsd/sys/arm/freescale/imx/imx_epit.c (revision c99b67a7947ea215f9c1d44ec022680e98920cd1)
1 /*-
2  * Copyright (c) 2017 Ian Lepore <ian@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$");
29 
30 /*
31  * Driver for imx Enhanced Programmable Interval Timer, a simple free-running
32  * counter device that can be used as the system timecounter.  On imx5 a second
33  * instance of the device is used as the system eventtimer.
34  */
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/bus.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
41 #include <sys/malloc.h>
42 #include <sys/rman.h>
43 #include <sys/timeet.h>
44 #include <sys/timetc.h>
45 #include <sys/watchdog.h>
46 #include <machine/bus.h>
47 #include <machine/cpu.h>
48 #include <machine/intr.h>
49 #include <machine/machdep.h>
50 
51 #include <dev/fdt/fdt_common.h>
52 #include <dev/ofw/openfirm.h>
53 #include <dev/ofw/ofw_bus.h>
54 #include <dev/ofw/ofw_bus_subr.h>
55 
56 #include <arm/freescale/imx/imx_ccmvar.h>
57 #include <arm/freescale/imx/imx_machdep.h>
58 
59 #define	EPIT_CR				0x00		/* Control register */
60 #define	  EPIT_CR_CLKSRC_SHIFT		  24
61 #define	  EPIT_CR_CLKSRC_OFF		   0
62 #define	  EPIT_CR_CLKSRC_IPG		   1
63 #define	  EPIT_CR_CLKSRC_HFCLK		   2
64 #define	  EPIT_CR_CLKSRC_LFCLK		   3
65 #define	  EPIT_CR_STOPEN		  (1u << 21)
66 #define	  EPIT_CR_WAITEN		  (1u << 19)
67 #define	  EPIT_CR_DBGEN			  (1u << 18)
68 #define	  EPIT_CR_IOVW			  (1u << 17)
69 #define	  EPIT_CR_SWR			  (1u << 16)
70 #define	  EPIT_CR_RLD			  (1u <<  3)
71 #define	  EPIT_CR_OCIEN			  (1u <<  2)
72 #define	  EPIT_CR_ENMOD			  (1u <<  1)
73 #define	  EPIT_CR_EN			  (1u <<  0)
74 
75 #define	EPIT_SR				0x04		/* Status register */
76 #define	  EPIT_SR_OCIF			  (1u << 0)
77 
78 #define	EPIT_LR				0x08		/* Load register */
79 #define	EPIT_CMPR			0x0c		/* Compare register */
80 #define	EPIT_CNR			0x10		/* Counter register */
81 
82 /*
83  * Define event timer limits.
84  *
85  * In theory our minimum period is 1 tick, because to setup a oneshot we don't
86  * need a read-modify-write sequence to calculate and set a compare register
87  * value while the counter is running.  In practice the waveform diagrams in the
88  * manual make it appear that a setting of 1 might cause it to miss the event,
89  * so I'm setting the lower limit to 2 ticks.
90  */
91 #define	ET_MIN_TICKS	2
92 #define	ET_MAX_TICKS	0xfffffffe
93 
94 static u_int epit_tc_get_timecount(struct timecounter *tc);
95 
96 struct epit_softc {
97 	device_t 		dev;
98 	struct resource *	memres;
99 	struct resource *	intres;
100 	void *			inthandle;
101 	uint32_t 		clkfreq;
102 	uint32_t 		ctlreg;
103 	uint32_t		period;
104 	struct timecounter	tc;
105 	struct eventtimer	et;
106 	bool			oneshot;
107 };
108 
109 #ifndef MULTIDELAY
110 /* Global softc pointer for use in DELAY(). */
111 static struct epit_softc *epit_sc;
112 #endif
113 
114 /*
115  * Probe data.  For some reason, the standard linux dts files don't have
116  * compatible properties on the epit devices (other properties are missing too,
117  * like clocks, but we don't care as much about that).  So our probe routine
118  * uses the name of the node (must contain "epit") and the address of the
119  * registers as identifying marks.
120  */
121 static const uint32_t imx51_epit_ioaddr[2] = {0x73fac000, 0x73fb0000};
122 static const uint32_t imx53_epit_ioaddr[2] = {0x53fac000, 0x53fb0000};
123 static const uint32_t imx6_epit_ioaddr[2]  = {0x020d0000, 0x020d4000};
124 
125 /* ocd_data is number of units to instantiate on the platform */
126 static struct ofw_compat_data compat_data[] = {
127 	{"fsl,imx6ul-epit", 1},
128 	{"fsl,imx6sx-epit", 1},
129 	{"fsl,imx6q-epit",  1},
130 	{"fsl,imx6dl-epit", 1},
131 	{"fsl,imx53-epit",  2},
132 	{"fsl,imx51-epit",  2},
133 	{"fsl,imx31-epit",  2},
134 	{"fsl,imx27-epit",  2},
135 	{"fsl,imx25-epit",  2},
136 	{NULL,              0}
137 };
138 
139 static inline uint32_t
140 RD4(struct epit_softc *sc, bus_size_t offset)
141 {
142 
143 	return (bus_read_4(sc->memres, offset));
144 }
145 
146 static inline void
147 WR4(struct epit_softc *sc, bus_size_t offset, uint32_t value)
148 {
149 
150 	bus_write_4(sc->memres, offset, value);
151 }
152 
153 static inline void
154 WR4B(struct epit_softc *sc, bus_size_t offset, uint32_t value)
155 {
156 
157 	bus_write_4(sc->memres, offset, value);
158 	bus_barrier(sc->memres, offset, 4, BUS_SPACE_BARRIER_WRITE);
159 }
160 
161 static u_int
162 epit_read_counter(struct epit_softc *sc)
163 {
164 
165 	/*
166 	 * Hardware is a downcounter, adjust to look like it counts up for use
167 	 * with timecounter and DELAY.
168 	 */
169 	return (0xffffffff - RD4(sc, EPIT_CNR));
170 }
171 
172 static void
173 epit_do_delay(int usec, void *arg)
174 {
175 	struct epit_softc *sc = arg;
176 	uint64_t curcnt, endcnt, startcnt, ticks;
177 
178 	/*
179 	 * Calculate the tick count with 64-bit values so that it works for any
180 	 * clock frequency.  Loop until the hardware count reaches start+ticks.
181 	 * If the 32-bit hardware count rolls over while we're looping, just
182 	 * manually do a carry into the high bits after each read; don't worry
183 	 * that doing this on each loop iteration is inefficient -- we're trying
184 	 * to waste time here.
185 	 */
186 	ticks = 1 + ((uint64_t)usec * sc->clkfreq) / 1000000;
187 	curcnt = startcnt = epit_read_counter(sc);
188 	endcnt = startcnt + ticks;
189 	while (curcnt < endcnt) {
190 		curcnt = epit_read_counter(sc);
191 		if (curcnt < startcnt)
192 			curcnt += 1ULL << 32;
193 	}
194 }
195 
196 static u_int
197 epit_tc_get_timecount(struct timecounter *tc)
198 {
199 
200 	return (epit_read_counter(tc->tc_priv));
201 }
202 
203 static int
204 epit_tc_attach(struct epit_softc *sc)
205 {
206 
207 	/* When the counter hits zero, reload with 0xffffffff.  Start it. */
208 	WR4(sc, EPIT_LR, 0xffffffff);
209 	WR4(sc, EPIT_CR, sc->ctlreg | EPIT_CR_EN);
210 
211 	/* Register as a timecounter. */
212 	sc->tc.tc_name          = "EPIT";
213 	sc->tc.tc_quality       = 1000;
214 	sc->tc.tc_frequency     = sc->clkfreq;
215 	sc->tc.tc_counter_mask  = 0xffffffff;
216 	sc->tc.tc_get_timecount = epit_tc_get_timecount;
217 	sc->tc.tc_priv          = sc;
218 	tc_init(&sc->tc);
219 
220 	/* We are the DELAY() implementation. */
221 #ifdef MULTIDELAY
222 	arm_set_delay(epit_do_delay, sc);
223 #else
224 	epit_sc = sc;
225 #endif
226 	return (0);
227 }
228 
229 static int
230 epit_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
231 {
232 	struct epit_softc *sc;
233 	uint32_t ticks;
234 
235 	sc = (struct epit_softc *)et->et_priv;
236 
237 	/*
238 	 * Disable the timer and clear any pending status.  The timer may be
239 	 * running or may have just expired if we're called to reschedule the
240 	 * next event before the previous event time arrives.
241 	 */
242 	WR4(sc, EPIT_CR, sc->ctlreg);
243 	WR4(sc, EPIT_SR, EPIT_SR_OCIF);
244 	if (period != 0) {
245 		sc->oneshot = false;
246 		ticks = ((uint32_t)et->et_frequency * period) >> 32;
247 	} else if (first != 0) {
248 		sc->oneshot = true;
249 		ticks = ((uint32_t)et->et_frequency * first) >> 32;
250 	} else {
251 		return (EINVAL);
252 	}
253 
254 	/* Set the countdown load register and start the timer. */
255 	WR4(sc, EPIT_LR, ticks);
256 	WR4B(sc, EPIT_CR, sc->ctlreg | EPIT_CR_EN);
257 
258 	return (0);
259 }
260 
261 static int
262 epit_et_stop(struct eventtimer *et)
263 {
264 	struct epit_softc *sc;
265 
266 	sc = (struct epit_softc *)et->et_priv;
267 
268 	/* Disable the timer and clear any pending status. */
269 	WR4(sc, EPIT_CR, sc->ctlreg);
270 	WR4B(sc, EPIT_SR, EPIT_SR_OCIF);
271 
272 	return (0);
273 }
274 
275 static int
276 epit_intr(void *arg)
277 {
278 	struct epit_softc *sc;
279 	uint32_t status;
280 
281 	sc = arg;
282 
283 	/*
284 	 * Disable a one-shot timer until a new event is scheduled so that the
285 	 * counter doesn't wrap and fire again.  Do this before clearing the
286 	 * status since a short period would make it fire again really soon.
287 	 *
288 	 * Clear interrupt status before invoking event callbacks.  The callback
289 	 * often sets up a new one-shot timer event and if the interval is short
290 	 * enough it can fire before we get out of this function.  If we cleared
291 	 * at the bottom we'd miss the interrupt and hang until the clock wraps.
292 	 */
293 	if (sc->oneshot)
294 		WR4(sc, EPIT_CR, sc->ctlreg);
295 
296 	status = RD4(sc, EPIT_SR);
297 	WR4B(sc, EPIT_SR, status);
298 
299 	if ((status & EPIT_SR_OCIF) == 0)
300 		return (FILTER_STRAY);
301 
302 	if (sc->et.et_active)
303 		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
304 
305 	return (FILTER_HANDLED);
306 }
307 
308 static int
309 epit_et_attach(struct epit_softc *sc)
310 {
311 	int err, rid;
312 
313 	rid = 0;
314 	sc->intres = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &rid,
315 	    RF_ACTIVE);
316 	if (sc->intres == NULL) {
317 		device_printf(sc->dev, "could not allocate interrupt\n");
318 		return (ENXIO);
319 	}
320 
321 	err = bus_setup_intr(sc->dev, sc->intres, INTR_TYPE_CLK | INTR_MPSAFE,
322 	    epit_intr, NULL, sc, &sc->inthandle);
323 	if (err != 0) {
324 		device_printf(sc->dev, "unable to setup the irq handler\n");
325 		return (err);
326 	}
327 
328 	/* To be an eventtimer, we need interrupts enabled. */
329 	sc->ctlreg |= EPIT_CR_OCIEN;
330 
331 	/* Register as an eventtimer. */
332 	sc->et.et_name = "EPIT";
333 	sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
334 	sc->et.et_quality = 1000;
335 	sc->et.et_frequency = sc->clkfreq;
336 	sc->et.et_min_period = ((uint64_t)ET_MIN_TICKS  << 32) / sc->clkfreq;
337 	sc->et.et_max_period = ((uint64_t)ET_MAX_TICKS  << 32) / sc->clkfreq;
338 	sc->et.et_start = epit_et_start;
339 	sc->et.et_stop = epit_et_stop;
340 	sc->et.et_priv = sc;
341 	et_register(&sc->et);
342 
343 	return (0);
344 }
345 
346 static int
347 epit_probe(device_t dev)
348 {
349 	struct resource *memres;
350 	rman_res_t ioaddr;
351 	int num_units, rid, unit;
352 
353 	if (!ofw_bus_status_okay(dev))
354 		return (ENXIO);
355 
356 	/*
357 	 * The FDT data for imx5 and imx6 EPIT hardware is missing or broken,
358 	 * but it may get fixed some day, so first just do a normal check.  We
359 	 * return success if the compatible string matches and we haven't
360 	 * already instantiated the number of units needed on this platform.
361 	 */
362 	unit = device_get_unit(dev);
363 	num_units = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
364 	if (unit < num_units) {
365 		device_set_desc(dev, "i.MX EPIT timer");
366 		return (BUS_PROBE_DEFAULT);
367 	}
368 
369 	/*
370 	 * No compat string match, but for imx6 all the data we need is in the
371 	 * node except the compat string, so do our own compatibility check
372 	 * using the device name of the node and the register block address.
373 	 */
374 	if (strstr(ofw_bus_get_name(dev), "epit") == NULL)
375 		return (ENXIO);
376 
377 	rid = 0;
378 	memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_UNMAPPED);
379 	if (memres == NULL)
380 		return (ENXIO);
381 	ioaddr = rman_get_start(memres);
382 	bus_free_resource(dev, SYS_RES_MEMORY, memres);
383 
384 	if (imx_soc_family() == 6) {
385 		if (unit > 0)
386 			return (ENXIO);
387 		if (ioaddr != imx6_epit_ioaddr[unit])
388 			return (ENXIO);
389 	} else {
390 		if (unit > 1)
391 			return (ENXIO);
392 		switch (imx_soc_type()) {
393 		case IMXSOC_51:
394 			if (ioaddr != imx51_epit_ioaddr[unit])
395 				return (ENXIO);
396 			break;
397 		case IMXSOC_53:
398 			if (ioaddr != imx53_epit_ioaddr[unit])
399 				return (ENXIO);
400 			break;
401 		default:
402 			return (ENXIO);
403 		}
404 		/*
405 		 * XXX Right now we have no way to handle the fact that the
406 		 * entire EPIT node is missing, which means no interrupt data.
407 		 */
408 		return (ENXIO);
409 	}
410 
411 	device_set_desc(dev, "i.MX EPIT timer");
412 	return (BUS_PROBE_DEFAULT);
413 }
414 
415 static int
416 epit_attach(device_t dev)
417 {
418 	struct epit_softc *sc;
419 	int err, rid;
420 	uint32_t clksrc;
421 
422 	sc = device_get_softc(dev);
423 	sc->dev = dev;
424 
425 	rid = 0;
426 	sc->memres = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &rid,
427 	    RF_ACTIVE);
428 	if (sc->memres == NULL) {
429 		device_printf(sc->dev, "could not allocate registers\n");
430 		return (ENXIO);
431 	}
432 
433 	/*
434 	 * For now, use ipg (66 MHz).  Some day we should get this from fdt.
435 	 */
436 	clksrc = EPIT_CR_CLKSRC_IPG;
437 
438 	switch (clksrc) {
439 	default:
440 		device_printf(dev,
441 		    "Unsupported clock source '%d', using IPG\n", clksrc);
442                 /* FALLTHROUGH */
443 	case EPIT_CR_CLKSRC_IPG:
444 		sc->clkfreq = imx_ccm_ipg_hz();
445 		break;
446 	case EPIT_CR_CLKSRC_HFCLK:
447 		sc->clkfreq = imx_ccm_perclk_hz();
448 		break;
449 	case EPIT_CR_CLKSRC_LFCLK:
450 		sc->clkfreq = 32768;
451 		break;
452 	}
453 
454 	/*
455 	 * Init: stop operations and clear all options, then set up options and
456 	 * clock source, then do a soft-reset and wait for it to complete.
457 	 */
458 	WR4(sc, EPIT_CR, 0);
459 
460 	sc->ctlreg =
461 	    (clksrc << EPIT_CR_CLKSRC_SHIFT) |  /* Use selected clock */
462 	    EPIT_CR_ENMOD  |                    /* Reload counter on enable */
463 	    EPIT_CR_RLD    |                    /* Reload counter from LR */
464 	    EPIT_CR_STOPEN |                    /* Run in STOP mode */
465 	    EPIT_CR_WAITEN |                    /* Run in WAIT mode */
466 	    EPIT_CR_DBGEN;                      /* Run in DEBUG mode */
467 
468 	WR4B(sc, EPIT_CR, sc->ctlreg | EPIT_CR_SWR);
469 	while (RD4(sc, EPIT_CR) & EPIT_CR_SWR)
470 		continue;
471 
472 	/*
473 	 * Unit 0 is the timecounter, 1 (if instantiated) is the eventtimer.
474 	 */
475 	if (device_get_unit(sc->dev) == 0)
476 		err = epit_tc_attach(sc);
477 	else
478 		err = epit_et_attach(sc);
479 
480 	return (err);
481 }
482 
483 static device_method_t epit_methods[] = {
484 	DEVMETHOD(device_probe,		epit_probe),
485 	DEVMETHOD(device_attach,	epit_attach),
486 
487 	DEVMETHOD_END
488 };
489 
490 static driver_t epit_driver = {
491 	"imx_epit",
492 	epit_methods,
493 	sizeof(struct epit_softc),
494 };
495 
496 static devclass_t epit_devclass;
497 
498 EARLY_DRIVER_MODULE(imx_epit, simplebus, epit_driver, epit_devclass, 0,
499     0, BUS_PASS_TIMER);
500 
501 #ifndef MULTIDELAY
502 
503 /*
504  * Hand-calibrated delay-loop counter.  This was calibrated on an i.MX6 running
505  * at 792mhz.  It will delay a bit too long on slower processors -- that's
506  * better than not delaying long enough.  In practice this is unlikely to get
507  * used much since the clock driver is one of the first to start up, and once
508  * we're attached the delay loop switches to using the timer hardware.
509  */
510 static const int epit_delay_count = 78;
511 
512 void
513 DELAY(int usec)
514 {
515 	uint64_t ticks;
516 
517 	/* If the timer hardware is not accessible, just use a loop. */
518 	if (epit_sc == NULL) {
519 		while (usec-- > 0)
520 			for (ticks = 0; ticks < epit_delay_count; ++ticks)
521 				cpufunc_nullop();
522 		return;
523 	} else {
524 		epit_do_delay(usec, epit_sc);
525 	}
526 }
527 
528 #endif
529