void __init rockchip_timer_clock_source_init( int apb_clk ) { int v = apb_clk / TIMER_MIN_PCLK; /* 20101008,HSL,do not warn for 2818.*/ //WARN_ON(v * TIMER_MIN_PCLK != apb_clk); /* have bug */ S_INFO("%s::apb=%d,timer apb=%d\n",__func__,apb_clk,v); spin_lock( &rockchip_timer_spinlock ); rockchip_apb_clk = v ; RK_TIMER_DISABLE(TIMER_CLKSRC); TIMER_SET_ROUNDUS(); #if !CHIP_RK281X RK_TIMER_INT_ENABLE( TIMER_CLKSRC ); #else RK_TIMER_INT_DISABLE( TIMER_CLKSRC ); #endif RK_TIMER_SETMODE_USER( TIMER_CLKSRC ); RK_TIMER_DISABLE(TIMER_CLKEVT); RK_TIMER_INT_ENABLE( TIMER_CLKEVT ); RK_TIMER_SETMODE_USER( TIMER_CLKEVT ); spin_unlock( &rockchip_timer_spinlock ); }
irqreturn_t rockchip_timer_clockuser_interrupt(int irq, void *dev_id) { RK_TIMER_INT_CLEAR(TIMER_CLKUSB); RK_TIMER_DISABLE(TIMER_CLKUSB); if(g_user_callback) g_user_callback(); return IRQ_HANDLED; }
void rockchip_timer_freeze(int freeze ) { unsigned long flags; local_irq_save( flags ); if( freeze ) { clock_event_freeze_count = RK_TIMER_READVALUE(TIMER_CLKSRC); RK_TIMER_DISABLE(TIMER_CLKSRC); RK_TIMER_DISABLE(TIMER_CLKEVT); } else { RK_TIMER_SETCOUNT(TIMER_CLKSRC,clock_event_freeze_count); RK_TIMER_ENABLE(TIMER_CLKSRC); RK_TIMER_ENABLE(TIMER_CLKEVT); } clock_source_freezed = freeze; local_irq_restore(flags); }
int rockchip_usertimer_start(unsigned long usecs, int (*callback)(void)) { g_user_callback = callback; RK_TIMER_DISABLE(TIMER_CLKUSB); RK_TIMER_SETCOUNT(TIMER_CLKUSB, usecs*rockchip_apb_clk); RK_TIMER_ENABLE(TIMER_CLKUSB); return 0; }
int rockchip_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { RK_TIMER_DISABLE(TIMER_CLKEVT); RK_TIMER_SETCOUNT(TIMER_CLKEVT,cycles*rockchip_apb_clk); RK_TIMER_ENABLE(TIMER_CLKEVT); return 0; /* 0: OK */ }
static int rk29_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { do { RK_TIMER_DISABLE(TIMER_CLKEVT); RK_TIMER_SETCOUNT(TIMER_CLKEVT, cycles); RK_TIMER_ENABLE(TIMER_CLKEVT); } while (RK_TIMER_READVALUE(TIMER_CLKEVT) > cycles); return 0; }
static int rk30_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { do { RK_TIMER_DISABLE(TIMER_CLKEVT); RK_TIMER_SETCOUNT(TIMER_CLKEVT, cycles); RK_TIMER_ENABLE(TIMER_CLKEVT); } while (rk30_timer_read_current_value(TIMER_CLKEVT) > cycles); return 0; }
irqreturn_t rockchip_timer_clockevent_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; //debug_gpio_reverse(); RK_TIMER_INT_CLEAR(TIMER_CLKEVT); if( evt->mode != CLOCK_EVT_MODE_PERIODIC ) RK_TIMER_DISABLE(TIMER_CLKEVT); evt->event_handler(evt); return IRQ_HANDLED; }
static void rk29_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: do { RK_TIMER_DISABLE(TIMER_CLKEVT); RK_TIMER_SETCOUNT(TIMER_CLKEVT, 24000000/HZ - 1); RK_TIMER_ENABLE(TIMER_CLKEVT); } while (RK_TIMER_READVALUE(TIMER_CLKEVT) > (24000000/HZ - 1)); break; case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_ONESHOT: break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: RK_TIMER_DISABLE(TIMER_CLKEVT); break; } }
static irqreturn_t rk29_timer_clockevent_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; RK_TIMER_INT_CLEAR(TIMER_CLKEVT); if (evt->mode == CLOCK_EVT_MODE_ONESHOT) RK_TIMER_DISABLE(TIMER_CLKEVT); evt->event_handler(evt); return IRQ_HANDLED; }
void rochchip_init_timer3( void ) { if( setup_irq(IRQ_NR_TIMER3,&timer3_irqa) ) { printk("request irq timer3 failed\n"); BUG(); } RK_TIMER_DISABLE(TIMER_CLKUSB); RK_TIMER_SETCOUNT(TIMER_CLKUSB, 150*1000 ); RK_TIMER_INT_ENABLE( TIMER_CLKUSB ); RK_TIMER_SETMODE_USER( TIMER_CLKUSB ); RK_TIMER_ENABLE(TIMER_CLKUSB); }
static void rk2928_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { switch (mode) { case CLOCK_EVT_MODE_PERIODIC: rk2928_timer_set_next_event(24000000 / HZ - 1, evt); break; case CLOCK_EVT_MODE_RESUME: case CLOCK_EVT_MODE_ONESHOT: break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: RK_TIMER_DISABLE(TIMER_CLKEVT); break; } }
static void __init rk29_timer_init_clocksource(void) { static char err[] __initdata = KERN_ERR "%s: can't register clocksource!\n"; struct clocksource *cs = &rk29_timer_clocksource; struct clk *clk = clk_get(NULL, TIMER_CLKSRC_NAME); struct clk *xin24m = clk_get(NULL, "xin24m"); clk_set_parent(clk, xin24m); RK_TIMER_DISABLE(TIMER_CLKSRC); RK_TIMER_SETCOUNT(TIMER_CLKSRC, 0xFFFFFFFF); RK_TIMER_ENABLE_FREE_RUNNING(TIMER_CLKSRC); cs->mult = MULT; if (clocksource_register(cs)) printk(err, cs->name); }
static __init int rk30_timer_init_clockevent(void) { struct clock_event_device *ce = &rk30_timer_clockevent; struct clk *clk = clk_get(NULL, TIMER_CLKEVT_NAME); struct clk *pclk = clk_get(NULL, "pclk_" TIMER_CLKEVT_NAME); clk_enable(pclk); clk_enable(clk); RK_TIMER_DISABLE(TIMER_CLKEVT); setup_irq(rk30_timer_clockevent_irq.irq, &rk30_timer_clockevent_irq); ce->irq = rk30_timer_clockevent_irq.irq; ce->cpumask = cpu_all_mask; clockevents_config_and_register(ce, 24000000, 0xF, 0xFFFFFFFF); return 0; }
static void __init rk30_timer_init_clocksource(void) { static char err[] __initdata = KERN_ERR "%s: can't register clocksource!\n"; struct clocksource *cs = &rk30_timer_clocksource; struct clk *clk = clk_get(NULL, TIMER_CLKSRC_NAME); struct clk *pclk = clk_get(NULL, "pclk_" TIMER_CLKSRC_NAME); clk_enable(pclk); clk_enable(clk); RK_TIMER_DISABLE(TIMER_CLKSRC); clk_disable(clk); RK_TIMER_SETCOUNT(TIMER_CLKSRC, 0xFFFFFFFF); RK_TIMER_ENABLE_FREE_RUNNING(TIMER_CLKSRC); clk_enable(clk); if (clocksource_register_hz(cs, 24000000)) printk(err, cs->name); }
/* * 20091120,HSL@RK,disable irq for enable timer and set count . * */ void rockchip_timer_clocksource_suspend_resume(int suspend ) { unsigned long flags; local_irq_save( flags ); RK_TIMER_DISABLE(TIMER_CLKEVT); #if 0 if( suspend ) { RK_TIMER_SETCOUNT(TIMER_CLKEVT,RK_CHECK_VBUS_COUNT*rockchip_apb_clk); RK_TIMER_ENABLE(TIMER_CLKEVT); } else { int cyl = RK_TIMER_GETCOUNT(TIMER_CLKEVT) - RK_TIMER_READVALUE(TIMER_CLKEVT); rktimer_update_suspend_ms( CHECK_VBUS_MS*cyl / RK_TIMER_GETCOUNT(TIMER_CLKEVT) ); } S_INFO("r/s timer,load cnt=0x%x,clk_source_suspend=%ld\n" , RK_TIMER_GETCOUNT(TIMER_CLKEVT), clk_source_suspend_second); #endif local_irq_restore(flags); }
static __init int rk29_timer_init_clockevent(void) { struct clock_event_device *ce = &rk29_timer_clockevent; struct clk *clk = clk_get(NULL, TIMER_CLKEVT_NAME); struct clk *xin24m = clk_get(NULL, "xin24m"); clk_set_parent(clk, xin24m); RK_TIMER_DISABLE(TIMER_CLKEVT); setup_irq(rk29_timer_clockevent_irq.irq, &rk29_timer_clockevent_irq); ce->mult = div_sc(24000000, NSEC_PER_SEC, ce->shift); ce->max_delta_ns = clockevent_delta2ns(0xFFFFFFFFUL, ce); ce->min_delta_ns = clockevent_delta2ns(1, ce) + 1; ce->cpumask = cpumask_of(0); clockevents_register_device(ce); return 0; }
void rockchip_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { // struct rockchip_clock *clock = container_of(evt, struct rockchip_clock, clockevent); switch (mode) { case CLOCK_EVT_MODE_RESUME: RK_TIMER_ENABLE(TIMER_CLKEVT); break; case CLOCK_EVT_MODE_PERIODIC: break; case CLOCK_EVT_MODE_ONESHOT: //RK_TIMER_DISABLE(TIMER_CLKEVT); //RK_TIMER_INT_ENABLE( TIMER_CLKEVT ); //RK_TIMER_SETMODE_USER( TIMER_CLKEVT ); //RK_TIMER_ENABLE(TIMER_CLKEVT); break; case CLOCK_EVT_MODE_UNUSED: break; case CLOCK_EVT_MODE_SHUTDOWN: RK_TIMER_DISABLE(TIMER_CLKEVT); break; } }