Lines Matching +full:imx5 +full:- +full:clock
1 /*-
29 * Driver for imx Enhanced Programmable Interval Timer, a simple free-running
30 * counter device that can be used as the system timecounter. On imx5 a second
84 * need a read-modify-write sequence to calculate and set a compare register
120 {"fsl,imx6ul-epit", 1},
121 {"fsl,imx6sx-epit", 1},
122 {"fsl,imx6q-epit", 1},
123 {"fsl,imx6dl-epit", 1},
124 {"fsl,imx53-epit", 2},
125 {"fsl,imx51-epit", 2},
126 {"fsl,imx31-epit", 2},
127 {"fsl,imx27-epit", 2},
128 {"fsl,imx25-epit", 2},
136 return (bus_read_4(sc->memres, offset)); in RD4()
143 bus_write_4(sc->memres, offset, value); in WR4()
150 bus_write_4(sc->memres, offset, value); in WR4B()
151 bus_barrier(sc->memres, offset, 4, BUS_SPACE_BARRIER_WRITE); in WR4B()
162 return (0xffffffff - RD4(sc, EPIT_CNR)); in epit_read_counter()
172 * Calculate the tick count with 64-bit values so that it works for any in epit_do_delay()
173 * clock frequency. Loop until the hardware count reaches start+ticks. in epit_do_delay()
174 * If the 32-bit hardware count rolls over while we're looping, just in epit_do_delay()
176 * that doing this on each loop iteration is inefficient -- we're trying in epit_do_delay()
179 ticks = 1 + ((uint64_t)usec * sc->clkfreq) / 1000000; in epit_do_delay()
193 return (epit_read_counter(tc->tc_priv)); in epit_tc_get_timecount()
202 WR4(sc, EPIT_CR, sc->ctlreg | EPIT_CR_EN); in epit_tc_attach()
205 sc->tc.tc_name = "EPIT"; in epit_tc_attach()
206 sc->tc.tc_quality = 1000; in epit_tc_attach()
207 sc->tc.tc_frequency = sc->clkfreq; in epit_tc_attach()
208 sc->tc.tc_counter_mask = 0xffffffff; in epit_tc_attach()
209 sc->tc.tc_get_timecount = epit_tc_get_timecount; in epit_tc_attach()
210 sc->tc.tc_priv = sc; in epit_tc_attach()
211 tc_init(&sc->tc); in epit_tc_attach()
225 sc = (struct epit_softc *)et->et_priv; in epit_et_start()
232 WR4(sc, EPIT_CR, sc->ctlreg); in epit_et_start()
235 sc->oneshot = false; in epit_et_start()
236 ticks = ((uint32_t)et->et_frequency * period) >> 32; in epit_et_start()
238 sc->oneshot = true; in epit_et_start()
239 ticks = ((uint32_t)et->et_frequency * first) >> 32; in epit_et_start()
246 WR4B(sc, EPIT_CR, sc->ctlreg | EPIT_CR_EN); in epit_et_start()
256 sc = (struct epit_softc *)et->et_priv; in epit_et_stop()
259 WR4(sc, EPIT_CR, sc->ctlreg); in epit_et_stop()
274 * Disable a one-shot timer until a new event is scheduled so that the in epit_intr()
279 * often sets up a new one-shot timer event and if the interval is short in epit_intr()
281 * at the bottom we'd miss the interrupt and hang until the clock wraps. in epit_intr()
283 if (sc->oneshot) in epit_intr()
284 WR4(sc, EPIT_CR, sc->ctlreg); in epit_intr()
292 if (sc->et.et_active) in epit_intr()
293 sc->et.et_event_cb(&sc->et, sc->et.et_arg); in epit_intr()
304 sc->intres = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &rid, in epit_et_attach()
306 if (sc->intres == NULL) { in epit_et_attach()
307 device_printf(sc->dev, "could not allocate interrupt\n"); in epit_et_attach()
311 err = bus_setup_intr(sc->dev, sc->intres, INTR_TYPE_CLK | INTR_MPSAFE, in epit_et_attach()
312 epit_intr, NULL, sc, &sc->inthandle); in epit_et_attach()
314 device_printf(sc->dev, "unable to setup the irq handler\n"); in epit_et_attach()
319 sc->ctlreg |= EPIT_CR_OCIEN; in epit_et_attach()
322 sc->et.et_name = "EPIT"; in epit_et_attach()
323 sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC; in epit_et_attach()
324 sc->et.et_quality = 1000; in epit_et_attach()
325 sc->et.et_frequency = sc->clkfreq; in epit_et_attach()
326 sc->et.et_min_period = ((uint64_t)ET_MIN_TICKS << 32) / sc->clkfreq; in epit_et_attach()
327 sc->et.et_max_period = ((uint64_t)ET_MAX_TICKS << 32) / sc->clkfreq; in epit_et_attach()
328 sc->et.et_start = epit_et_start; in epit_et_attach()
329 sc->et.et_stop = epit_et_stop; in epit_et_attach()
330 sc->et.et_priv = sc; in epit_et_attach()
331 et_register(&sc->et); in epit_et_attach()
347 * The FDT data for imx5 and imx6 EPIT hardware is missing or broken, in epit_probe()
353 num_units = ofw_bus_search_compatible(dev, compat_data)->ocd_data; in epit_probe()
413 sc->dev = dev; in epit_attach()
416 sc->memres = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &rid, in epit_attach()
418 if (sc->memres == NULL) { in epit_attach()
419 device_printf(sc->dev, "could not allocate registers\n"); in epit_attach()
431 "Unsupported clock source '%d', using IPG\n", clksrc); in epit_attach()
434 sc->clkfreq = imx_ccm_ipg_hz(); in epit_attach()
437 sc->clkfreq = imx_ccm_perclk_hz(); in epit_attach()
440 sc->clkfreq = 32768; in epit_attach()
446 * clock source, then do a soft-reset and wait for it to complete. in epit_attach()
450 sc->ctlreg = in epit_attach()
451 (clksrc << EPIT_CR_CLKSRC_SHIFT) | /* Use selected clock */ in epit_attach()
458 WR4B(sc, EPIT_CR, sc->ctlreg | EPIT_CR_SWR); in epit_attach()
465 if (device_get_unit(sc->dev) == 0) in epit_attach()