static irqreturn_t mxs_nomatch_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *c = dev_id; /* timer 0 */ if (__raw_readl(online_timer->base + HW_TIMROT_TIMCTRLn(0)) & BM_TIMROT_TIMCTRLn_IRQ) { __raw_writel(BM_TIMROT_TIMCTRLn_IRQ, online_timer->base + HW_TIMROT_TIMCTRLn_CLR(0)); c->event_handler(c); } /* timer 1 */ else if (__raw_readl(online_timer->base + HW_TIMROT_TIMCTRLn(1)) & BM_TIMROT_TIMCTRLn_IRQ) { __raw_writel(BM_TIMROT_TIMCTRLn_IRQ, online_timer->base + HW_TIMROT_TIMCTRLn_CLR(1)); __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, online_timer->base + HW_TIMROT_TIMCTRLn_CLR(1)); __raw_writel(0xFFFF, online_timer->base + HW_TIMROT_TIMCOUNTn(1)); } return IRQ_HANDLED; }
static void __init mxs_timer_init(struct device_node *np) { struct clk *timer_clk; int irq; mxs_timrot_base = of_iomap(np, 0); WARN_ON(!mxs_timrot_base); timer_clk = of_clk_get(np, 0); if (IS_ERR(timer_clk)) { pr_err("%s: failed to get clk\n", __func__); return; } clk_prepare_enable(timer_clk); /* * 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 */ mxs_clocksource_init(timer_clk); mxs_clockevent_init(timer_clk); /* Make irqs happen */ irq = irq_of_parse_and_map(np, 0); setup_irq(irq, &mxs_timer_irq); }
void __init mxs_timer_init(int irq) { struct clk *timer_clk; timer_clk = clk_get_sys("timrot", NULL); if (IS_ERR(timer_clk)) { pr_err("%s: failed to get clk\n", __func__); return; } clk_prepare_enable(timer_clk); /* * Initialize timers to a known state */ mxs_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL); /* get timrot version */ timrot_major_version = __raw_readl(mxs_timrot_base + (cpu_is_mx23() ? 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__32KHZ_XTAL) | 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__32KHZ_XTAL) | 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 */ mxs_clocksource_init(timer_clk); mxs_clockevent_init(timer_clk); /* Make irqs happen */ setup_irq(irq, &mxs_timer_irq); }
/* * Set up timer interrupt, and return the current time in seconds. */ void mxs_nomatch_timer_init(struct mxs_sys_timer *timer) { if (online_timer) return; online_timer = timer; cksrc_mxs_nomatch.mult = clocksource_hz2mult(CLOCK_TICK_RATE, cksrc_mxs_nomatch.shift); ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, ckevt_timrot.shift); ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot); ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot); ckevt_timrot.cpumask = cpumask_of(0); /* clear two timers */ __raw_writel(0, online_timer->base + HW_TIMROT_TIMCOUNTn(0)); __raw_writel(0, online_timer->base + HW_TIMROT_TIMCOUNTn(1)); /* configure them */ __raw_writel( (8 << BP_TIMROT_TIMCTRLn_SELECT) | /* 32 kHz */ BM_TIMROT_TIMCTRLn_RELOAD | BM_TIMROT_TIMCTRLn_UPDATE | BM_TIMROT_TIMCTRLn_IRQ_EN, online_timer->base + HW_TIMROT_TIMCTRLn(0)); __raw_writel( (8 << BP_TIMROT_TIMCTRLn_SELECT) | /* 32 kHz */ BM_TIMROT_TIMCTRLn_RELOAD | BM_TIMROT_TIMCTRLn_UPDATE | BM_TIMROT_TIMCTRLn_IRQ_EN, online_timer->base + HW_TIMROT_TIMCTRLn(1)); __raw_writel(CLOCK_TICK_RATE / HZ - 1, online_timer->base + HW_TIMROT_TIMCOUNTn(0)); __raw_writel(0xFFFF, online_timer->base + HW_TIMROT_TIMCOUNTn(1)); setup_irq(IRQ_TIMER0, &mxs_nomatch_timer_irq); clocksource_register(&cksrc_mxs_nomatch); clockevents_register_device(&ckevt_timrot); }
static void beep_timer_off(void) { __raw_writel(1 << 2,int_base +HW_ICOLL_INTERRUPTn_CLR(IRQ_TIMER3)); __raw_writel(BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK| BM_TIMROT_TIMCTRLn_IRQ_EN , base + HW_TIMROT_TIMCTRLn(3)); gpio_direction_output(MXS_PIN_TO_GPIO(mxs_leds[LED_BEEP]), 0); return; }
void mxs_nomatch_resume_timer(void) { __raw_writel(BM_TIMROT_ROTCTRL_SFTRST | BM_TIMROT_ROTCTRL_CLKGATE, online_timer->base + HW_TIMROT_ROTCTRL_CLR); __raw_writel( 8 << BP_TIMROT_TIMCTRLn_SELECT | /* 32 kHz */ BM_TIMROT_TIMCTRLn_RELOAD | BM_TIMROT_TIMCTRLn_UPDATE | BM_TIMROT_TIMCTRLn_IRQ_EN, online_timer->base + HW_TIMROT_TIMCTRLn(0)); __raw_writel( 8 << BP_TIMROT_TIMCTRLn_SELECT | /* 32 kHz */ BM_TIMROT_TIMCTRLn_RELOAD | BM_TIMROT_TIMCTRLn_UPDATE | BM_TIMROT_TIMCTRLn_IRQ_EN, online_timer->base + HW_TIMROT_TIMCTRLn(1)); __raw_writel(CLOCK_TICK_RATE / HZ - 1, online_timer->base + HW_TIMROT_TIMCOUNTn(0)); __raw_writel(0xFFFF, online_timer->base + HW_TIMROT_TIMCOUNTn(1)); }
void imx233_timrot_setup(unsigned timer_nr, bool reload, unsigned count, unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn) { int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* only enable interrupt if function is set */ bool irq = fn != NULL; timer_fns[timer_nr] = fn; /* make sure we start from stop state */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR2(TIMROT_TIMCTRLn, SELECT(BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK), UPDATE(1)); /* write count and take effect immediately with UPDATE * manual says count-1 for reload timers */ HW_TIMROT_TIMCOUNTn(timer_nr) = reload ? count - 1 : count; /* start timer */ HW_TIMROT_TIMCTRLn(timer_nr) = BF_OR6(TIMROT_TIMCTRLn, SELECT(src), PRESCALE(prescale), POLARITY(polarity), RELOAD(reload), IRQ(irq), IRQ_EN(irq)); imx233_icoll_enable_interrupt(INT_SRC_TIMER(timer_nr), irq); restore_interrupt(oldstatus); }
static int beep_timer_on(void) { #if 0 //modify by cxf in 2014-04-03 writel(3 << 12,beep_base + HW_PINCTRL_MUXSEL4_SET); writel(3 << 24,beep_base + HW_PINCTRL_DRIVE8_SET); writel(1 << 23,beep_base + HW_PINCTRL_DRIVE8_CLR); writel(1 << 6,beep_base + HW_PINCTRL_DOE2_SET); #endif __raw_writel(BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS| BM_TIMROT_TIMCTRLn_IRQ_EN , base + HW_TIMROT_TIMCTRLn(3)); __raw_writel((0x0f | (3ul << 6)|(1ul << 14)),base + HW_TIMROT_TIMCTRL3_SET); __raw_writel(3ul << 4,base + HW_TIMROT_TIMCTRL3_CLR); __raw_writel(TIMER_CLOCK_FREQ / TICK_PER_SEC,base + HW_TIMROT_FIXED_COUNT3); __raw_writel(1 << 2,int_base +HW_ICOLL_INTERRUPTn_CLR(IRQ_TIMER3)); __raw_writel(1 << 2,int_base +HW_ICOLL_INTERRUPTn_SET(IRQ_TIMER3)); return 0; }
static void timrot_irq_acknowledge(void) { __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base + HW_TIMROT_TIMCTRLn(0)); }
static inline void timrot_irq_enable(void) { __mxs_setl(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base + HW_TIMROT_TIMCTRLn(0)); }
static void timrot_irq_acknowledge(void) { __raw_writel(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base + HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR); }
static inline void timrot_irq_enable(void) { __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base + HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_SET); }