]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/freescale/imx/imx_epit.c
Merge llvm trunk r338150 (just before the 7.0.0 branch point), and
[FreeBSD/FreeBSD.git] / sys / arm / freescale / imx / imx_epit.c
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 /*
110  * Probe data.  For some reason, the standard linux dts files don't have
111  * compatible properties on the epit devices (other properties are missing too,
112  * like clocks, but we don't care as much about that).  So our probe routine
113  * uses the name of the node (must contain "epit") and the address of the
114  * registers as identifying marks.
115  */
116 static const uint32_t imx51_epit_ioaddr[2] = {0x73fac000, 0x73fb0000};
117 static const uint32_t imx53_epit_ioaddr[2] = {0x53fac000, 0x53fb0000};
118 static const uint32_t imx6_epit_ioaddr[2]  = {0x020d0000, 0x020d4000};
119
120 /* ocd_data is number of units to instantiate on the platform */
121 static struct ofw_compat_data compat_data[] = {
122         {"fsl,imx6ul-epit", 1},
123         {"fsl,imx6sx-epit", 1},
124         {"fsl,imx6q-epit",  1},
125         {"fsl,imx6dl-epit", 1},
126         {"fsl,imx53-epit",  2},
127         {"fsl,imx51-epit",  2},
128         {"fsl,imx31-epit",  2},
129         {"fsl,imx27-epit",  2},
130         {"fsl,imx25-epit",  2},
131         {NULL,              0}
132 };
133
134 static inline uint32_t
135 RD4(struct epit_softc *sc, bus_size_t offset)
136 {
137
138         return (bus_read_4(sc->memres, offset));
139 }
140
141 static inline void
142 WR4(struct epit_softc *sc, bus_size_t offset, uint32_t value)
143 {
144
145         bus_write_4(sc->memres, offset, value);
146 }
147
148 static inline void
149 WR4B(struct epit_softc *sc, bus_size_t offset, uint32_t value)
150 {
151
152         bus_write_4(sc->memres, offset, value);
153         bus_barrier(sc->memres, offset, 4, BUS_SPACE_BARRIER_WRITE);
154 }
155
156 static u_int
157 epit_read_counter(struct epit_softc *sc)
158 {
159
160         /*
161          * Hardware is a downcounter, adjust to look like it counts up for use
162          * with timecounter and DELAY.
163          */
164         return (0xffffffff - RD4(sc, EPIT_CNR));
165 }
166
167 static void
168 epit_do_delay(int usec, void *arg)
169 {
170         struct epit_softc *sc = arg;
171         uint64_t curcnt, endcnt, startcnt, ticks;
172
173         /*
174          * Calculate the tick count with 64-bit values so that it works for any
175          * clock frequency.  Loop until the hardware count reaches start+ticks.
176          * If the 32-bit hardware count rolls over while we're looping, just
177          * manually do a carry into the high bits after each read; don't worry
178          * that doing this on each loop iteration is inefficient -- we're trying
179          * to waste time here.
180          */
181         ticks = 1 + ((uint64_t)usec * sc->clkfreq) / 1000000;
182         curcnt = startcnt = epit_read_counter(sc);
183         endcnt = startcnt + ticks;
184         while (curcnt < endcnt) {
185                 curcnt = epit_read_counter(sc);
186                 if (curcnt < startcnt)
187                         curcnt += 1ULL << 32;
188         }
189 }
190
191 static u_int
192 epit_tc_get_timecount(struct timecounter *tc)
193 {
194
195         return (epit_read_counter(tc->tc_priv));
196 }
197
198 static int
199 epit_tc_attach(struct epit_softc *sc)
200 {
201
202         /* When the counter hits zero, reload with 0xffffffff.  Start it. */
203         WR4(sc, EPIT_LR, 0xffffffff);
204         WR4(sc, EPIT_CR, sc->ctlreg | EPIT_CR_EN);
205
206         /* Register as a timecounter. */
207         sc->tc.tc_name          = "EPIT";
208         sc->tc.tc_quality       = 1000;
209         sc->tc.tc_frequency     = sc->clkfreq;
210         sc->tc.tc_counter_mask  = 0xffffffff;
211         sc->tc.tc_get_timecount = epit_tc_get_timecount;
212         sc->tc.tc_priv          = sc;
213         tc_init(&sc->tc);
214
215         /* We are the DELAY() implementation. */
216         arm_set_delay(epit_do_delay, sc);
217
218         return (0);
219 }
220
221 static int
222 epit_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
223 {
224         struct epit_softc *sc;
225         uint32_t ticks;
226
227         sc = (struct epit_softc *)et->et_priv;
228
229         /*
230          * Disable the timer and clear any pending status.  The timer may be
231          * running or may have just expired if we're called to reschedule the
232          * next event before the previous event time arrives.
233          */
234         WR4(sc, EPIT_CR, sc->ctlreg);
235         WR4(sc, EPIT_SR, EPIT_SR_OCIF);
236         if (period != 0) {
237                 sc->oneshot = false;
238                 ticks = ((uint32_t)et->et_frequency * period) >> 32;
239         } else if (first != 0) {
240                 sc->oneshot = true;
241                 ticks = ((uint32_t)et->et_frequency * first) >> 32;
242         } else {
243                 return (EINVAL);
244         }
245
246         /* Set the countdown load register and start the timer. */
247         WR4(sc, EPIT_LR, ticks);
248         WR4B(sc, EPIT_CR, sc->ctlreg | EPIT_CR_EN);
249
250         return (0);
251 }
252
253 static int
254 epit_et_stop(struct eventtimer *et)
255 {
256         struct epit_softc *sc;
257
258         sc = (struct epit_softc *)et->et_priv;
259
260         /* Disable the timer and clear any pending status. */
261         WR4(sc, EPIT_CR, sc->ctlreg);
262         WR4B(sc, EPIT_SR, EPIT_SR_OCIF);
263
264         return (0);
265 }
266
267 static int
268 epit_intr(void *arg)
269 {
270         struct epit_softc *sc;
271         uint32_t status;
272
273         sc = arg;
274
275         /*
276          * Disable a one-shot timer until a new event is scheduled so that the
277          * counter doesn't wrap and fire again.  Do this before clearing the
278          * status since a short period would make it fire again really soon.
279          *
280          * Clear interrupt status before invoking event callbacks.  The callback
281          * often sets up a new one-shot timer event and if the interval is short
282          * enough it can fire before we get out of this function.  If we cleared
283          * at the bottom we'd miss the interrupt and hang until the clock wraps.
284          */
285         if (sc->oneshot)
286                 WR4(sc, EPIT_CR, sc->ctlreg);
287
288         status = RD4(sc, EPIT_SR);
289         WR4B(sc, EPIT_SR, status);
290
291         if ((status & EPIT_SR_OCIF) == 0)
292                 return (FILTER_STRAY);
293
294         if (sc->et.et_active)
295                 sc->et.et_event_cb(&sc->et, sc->et.et_arg);
296
297         return (FILTER_HANDLED);
298 }
299
300 static int
301 epit_et_attach(struct epit_softc *sc)
302 {
303         int err, rid;
304
305         rid = 0;
306         sc->intres = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &rid,
307             RF_ACTIVE);
308         if (sc->intres == NULL) {
309                 device_printf(sc->dev, "could not allocate interrupt\n");
310                 return (ENXIO);
311         }
312
313         err = bus_setup_intr(sc->dev, sc->intres, INTR_TYPE_CLK | INTR_MPSAFE,
314             epit_intr, NULL, sc, &sc->inthandle);
315         if (err != 0) {
316                 device_printf(sc->dev, "unable to setup the irq handler\n");
317                 return (err);
318         }
319
320         /* To be an eventtimer, we need interrupts enabled. */
321         sc->ctlreg |= EPIT_CR_OCIEN;
322
323         /* Register as an eventtimer. */
324         sc->et.et_name = "EPIT";
325         sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
326         sc->et.et_quality = 1000;
327         sc->et.et_frequency = sc->clkfreq;
328         sc->et.et_min_period = ((uint64_t)ET_MIN_TICKS  << 32) / sc->clkfreq;
329         sc->et.et_max_period = ((uint64_t)ET_MAX_TICKS  << 32) / sc->clkfreq;
330         sc->et.et_start = epit_et_start;
331         sc->et.et_stop = epit_et_stop;
332         sc->et.et_priv = sc;
333         et_register(&sc->et);
334
335         return (0);
336 }
337
338 static int
339 epit_probe(device_t dev)
340 {
341         struct resource *memres;
342         rman_res_t ioaddr;
343         int num_units, rid, unit;
344
345         if (!ofw_bus_status_okay(dev))
346                 return (ENXIO);
347
348         /*
349          * The FDT data for imx5 and imx6 EPIT hardware is missing or broken,
350          * but it may get fixed some day, so first just do a normal check.  We
351          * return success if the compatible string matches and we haven't
352          * already instantiated the number of units needed on this platform.
353          */
354         unit = device_get_unit(dev);
355         num_units = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
356         if (unit < num_units) {
357                 device_set_desc(dev, "i.MX EPIT timer");
358                 return (BUS_PROBE_DEFAULT);
359         }
360
361         /*
362          * No compat string match, but for imx6 all the data we need is in the
363          * node except the compat string, so do our own compatibility check
364          * using the device name of the node and the register block address.
365          */
366         if (strstr(ofw_bus_get_name(dev), "epit") == NULL)
367                 return (ENXIO);
368
369         rid = 0;
370         memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_UNMAPPED);
371         if (memres == NULL)
372                 return (ENXIO);
373         ioaddr = rman_get_start(memres);
374         bus_free_resource(dev, SYS_RES_MEMORY, memres);
375
376         if (imx_soc_family() == 6) {
377                 if (unit > 0)
378                         return (ENXIO);
379                 if (ioaddr != imx6_epit_ioaddr[unit])
380                         return (ENXIO);
381         } else {
382                 if (unit > 1)
383                         return (ENXIO);
384                 switch (imx_soc_type()) {
385                 case IMXSOC_51:
386                         if (ioaddr != imx51_epit_ioaddr[unit])
387                                 return (ENXIO);
388                         break;
389                 case IMXSOC_53:
390                         if (ioaddr != imx53_epit_ioaddr[unit])
391                                 return (ENXIO);
392                         break;
393                 default:
394                         return (ENXIO);
395                 }
396                 /*
397                  * XXX Right now we have no way to handle the fact that the
398                  * entire EPIT node is missing, which means no interrupt data.
399                  */
400                 return (ENXIO);
401         }
402
403         device_set_desc(dev, "i.MX EPIT timer");
404         return (BUS_PROBE_DEFAULT);
405 }
406
407 static int
408 epit_attach(device_t dev)
409 {
410         struct epit_softc *sc;
411         int err, rid;
412         uint32_t clksrc;
413
414         sc = device_get_softc(dev);
415         sc->dev = dev;
416
417         rid = 0;
418         sc->memres = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &rid,
419             RF_ACTIVE);
420         if (sc->memres == NULL) {
421                 device_printf(sc->dev, "could not allocate registers\n");
422                 return (ENXIO);
423         }
424
425         /*
426          * For now, use ipg (66 MHz).  Some day we should get this from fdt.
427          */
428         clksrc = EPIT_CR_CLKSRC_IPG;
429
430         switch (clksrc) {
431         default:
432                 device_printf(dev, 
433                     "Unsupported clock source '%d', using IPG\n", clksrc);
434                 /* FALLTHROUGH */
435         case EPIT_CR_CLKSRC_IPG:
436                 sc->clkfreq = imx_ccm_ipg_hz();
437                 break;
438         case EPIT_CR_CLKSRC_HFCLK:
439                 sc->clkfreq = imx_ccm_perclk_hz();
440                 break;
441         case EPIT_CR_CLKSRC_LFCLK:
442                 sc->clkfreq = 32768;
443                 break;
444         }
445
446         /*
447          * Init: stop operations and clear all options, then set up options and
448          * clock source, then do a soft-reset and wait for it to complete.
449          */
450         WR4(sc, EPIT_CR, 0);
451
452         sc->ctlreg =
453             (clksrc << EPIT_CR_CLKSRC_SHIFT) |  /* Use selected clock */
454             EPIT_CR_ENMOD  |                    /* Reload counter on enable */
455             EPIT_CR_RLD    |                    /* Reload counter from LR */
456             EPIT_CR_STOPEN |                    /* Run in STOP mode */
457             EPIT_CR_WAITEN |                    /* Run in WAIT mode */
458             EPIT_CR_DBGEN;                      /* Run in DEBUG mode */
459
460         WR4B(sc, EPIT_CR, sc->ctlreg | EPIT_CR_SWR);
461         while (RD4(sc, EPIT_CR) & EPIT_CR_SWR)
462                 continue;
463
464         /*
465          * Unit 0 is the timecounter, 1 (if instantiated) is the eventtimer.
466          */
467         if (device_get_unit(sc->dev) == 0)
468                 err = epit_tc_attach(sc);
469         else
470                 err = epit_et_attach(sc);
471
472         return (err);
473 }
474
475 static device_method_t epit_methods[] = {
476         DEVMETHOD(device_probe,         epit_probe),
477         DEVMETHOD(device_attach,        epit_attach),
478
479         DEVMETHOD_END
480 };
481
482 static driver_t epit_driver = {
483         "imx_epit",
484         epit_methods,
485         sizeof(struct epit_softc),
486 };
487
488 static devclass_t epit_devclass;
489
490 EARLY_DRIVER_MODULE(imx_epit, simplebus, epit_driver, epit_devclass, 0,
491     0, BUS_PASS_TIMER);