/* * Override the global weak sched_clock symbol with this * local implementation which uses the clocksource to get some * better resolution when scheduling the kernel.
*/ static u64 notrace nomadik_read_sched_clock(void)
{ if (unlikely(!mtu_base)) return 0;
staticvoid nmdk_clkevt_reset(void)
{ if (clkevt_periodic) { /* Timer: configure load and background-load, and fire it up */
writel(nmdk_cycle, mtu_base + MTU_LR(1));
writel(nmdk_cycle, mtu_base + MTU_BGLR(1));
writel(MTU_CRn_PERIODIC | clk_prescale |
MTU_CRn_32BITS | MTU_CRn_ENA,
mtu_base + MTU_CR(1));
writel(1 << 1, mtu_base + MTU_IMSC);
} else { /* Generate an interrupt to start the clockevent again */
(void) nmdk_clkevt_next(nmdk_cycle, NULL);
}
}
/* ClockSource: configure load and background-load, and fire it up */
writel(nmdk_cycle, mtu_base + MTU_LR(0));
writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
/* * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz * for ux500, and in one specific Ux500 case 32768 Hz. * * Use a divide-by-16 counter if the tick rate is more than 32MHz. * At 32 MHz, the timer (with 32 bit counter) can be programmed * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer * with 16 gives too low timer resolution.
*/
rate = clk_get_rate(clk); if (rate > 32000000) {
rate /= 16;
clk_prescale = MTU_CRn_PRESCALE_16;
} else {
clk_prescale = MTU_CRn_PRESCALE_1;
}
/* Cycles for periodic mode */
nmdk_cycle = DIV_ROUND_CLOSEST(rate, HZ);
/* Timer 0 is the free running clocksource */
nmdk_clksrc_reset();
ret = clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0",
rate, 200, 32, clocksource_mmio_readl_down); if (ret) {
pr_err("timer: failed to initialize clock source %s\n", "mtu_0"); return ret;
}
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.