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