/* * There are 2 versions of the timrot on Freescale MXS-based SoCs. * The v1 on MX23 only gets 16 bits counter, while v2 on MX28 * extends the counter to 32 bits. * * The implementation uses two timers, one for clock_event and * another for clocksource. MX28 uses timrot 0 and 1, while MX23 * uses 0 and 2.
*/
/* * There are 4 registers for each timrotv2 instance, and 2 registers * for each timrotv1. So address step 0x40 in macros below strides * one instance of timrotv2 while two instances of timrotv1. * * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1 * on MX28 while timrot2 on MX23.
*/ /* common between v1 and v2 */ #define HW_TIMROT_ROTCTRL 0x00 #define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40) /* v1 only */ #define HW_TIMROT_TIMCOUNTn(n) (0x30 + (n) * 0x40) /* v2 only */ #define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40) #define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
/* Set event time into the furthest future */ if (timrot_is_v1())
__raw_writel(0xffff, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1)); else
__raw_writel(0xffffffff,
mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
timer_clk = of_clk_get(np, 0); if (IS_ERR(timer_clk)) {
pr_err("%s: failed to get clk\n", __func__); return PTR_ERR(timer_clk);
}
ret = clk_prepare_enable(timer_clk); if (ret) return ret;
/* * Initialize timers to a known state
*/
stmp_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
/* get timrot version */
timrot_major_version = __raw_readl(mxs_timrot_base +
(of_device_is_compatible(np, "fsl,imx23-timrot") ?
MX23_TIMROT_VERSION_OFFSET :
MX28_TIMROT_VERSION_OFFSET));
timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
/* one for clock_event */
__raw_writel((timrot_is_v1() ?
BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
BM_TIMROT_TIMCTRLn_UPDATE |
BM_TIMROT_TIMCTRLn_IRQ_EN,
mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
/* another for clocksource */
__raw_writel((timrot_is_v1() ?
BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
BM_TIMROT_TIMCTRLn_RELOAD,
mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
/* set clocksource timer fixed count to the maximum */ if (timrot_is_v1())
__raw_writel(0xffff,
mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1)); else
__raw_writel(0xffffffff,
mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
/* init and register the timer to the framework */
ret = mxs_clocksource_init(timer_clk); if (ret) return ret;
ret = mxs_clockevent_init(timer_clk); if (ret) return ret;
/* Make irqs happen */
irq = irq_of_parse_and_map(np, 0); if (irq <= 0) return -EINVAL;
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.