/* * linux/arch/arm/mach-omap1/timer32k.c * * OMAP 32K Timer * * Copyright (C) 2004 - 2005 Nokia Corporation * Partial timer rewrite and additional dynamic tick timer support by * Tony Lindgen <tony@atomide.com> and * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> * OMAP Dual-mode timer framework support by Timo Teras * * MPU timer code based on the older MPU timer code for OMAP * Copyright (C) 2000 RidgeRun, Inc. * Author: Greg Lonnon <glonnon@ridgerun.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* * --------------------------------------------------------------------------- * 32KHz OS timer * * This currently works only on 16xx, as 1510 does not have the continuous * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer * on 1510 would be possible, but the timer would not be as accurate as * with the 32KHz synchronized timer. * ---------------------------------------------------------------------------
*/
/* * 32KHz clocksource ... always available, on pretty most chips except * OMAP 730 and 1510. Other timers could be used as clocksources, with * higher resolution in free-running counter modes (e.g. 12 MHz xtal), * but systems won't necessarily want to spend resources that way.
*/ staticvoid __iomem *sync32k_cnt_reg;
/** * omap_read_persistent_clock64 - Return time from a persistent clock. * @ts: &struct timespec64 for the returned time * * Reads the time from a source which isn't disabled during PM, the * 32k sync timer. Convert the cycles elapsed since last read into * nsecs and adds to a monotonically increasing timespec64.
*/ staticvoid omap_read_persistent_clock64(struct timespec64 *ts)
{ unsignedlonglong nsecs;
cycles_t last_cycles;
/** * omap_init_clocksource_32k - setup and register counter 32k as a * kernel clocksource * @vbase: base addr of counter_32k module * * Returns: %0 upon success or negative error code upon failure. *
*/ staticint __init omap_init_clocksource_32k(void __iomem *vbase)
{ int ret;
/* * 32k sync Counter IP register offsets vary between the * highlander version and the legacy ones. * The 'SCHEME' bits(30-31) of the revision register is used * to identify the version.
*/ if (readl_relaxed(vbase + OMAP2_32KSYNCNT_REV_OFF) &
OMAP2_32KSYNCNT_REV_SCHEME)
sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_HIGH; else
sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_LOW;
/* * 120000 rough estimate from the calculations in * __clocksource_update_freq_scale.
*/
clocks_calc_mult_shift(&persistent_mult, &persistent_shift,
32768, NSEC_PER_SEC, 120000);
ret = clocksource_mmio_init(sync32k_cnt_reg, "32k_counter", 32768,
250, 32, clocksource_mmio_readl_up); if (ret) {
pr_err("32k_counter: can't register clocksource\n"); return ret;
}
sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
register_persistent_clock(omap_read_persistent_clock64);
pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
return 0;
}
/* * --------------------------------------------------------------------------- * Timer initialization * ---------------------------------------------------------------------------
*/ int __init omap_32k_timer_init(void)
{ int ret = -ENODEV;
if (cpu_is_omap16xx()) { void __iomem *base; struct clk *sync32k_ick;
base = ioremap(OMAP1_32KSYNC_TIMER_BASE, SZ_1K); if (!base) {
pr_err("32k_counter: failed to map base addr\n"); return -ENODEV;
}
sync32k_ick = clk_get(NULL, "omap_32ksync_ick"); if (!IS_ERR(sync32k_ick))
clk_prepare_enable(sync32k_ick);
ret = omap_init_clocksource_32k(base);
}
if (!ret)
omap_init_32k_timer();
return ret;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.